From 9e6d039a3276c4502086044a827802295f3ad95d Mon Sep 17 00:00:00 2001 From: sudacode Date: Thu, 19 Feb 2026 00:48:02 -0800 Subject: [PATCH] fix(anki): fix Lapis sentence-card fields to defaults Remove configurable isLapis sentence/audio field overrides so sentence cards always map to Sentence and SentenceAudio. Update types and docs to reflect the simplified config surface. --- ...-card-field-config-to-fixed-field-names.md | 44 +++++++++++++++++++ docs/anki-integration.md | 6 +-- docs/configuration.md | 7 ++- docs/mining-workflow.md | 2 +- src/anki-integration.ts | 8 +--- src/config/definitions.ts | 2 - src/types.ts | 4 -- 7 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 backlog/tasks/task-83 - Simplify-isLapis-sentence-card-field-config-to-fixed-field-names.md diff --git a/backlog/tasks/task-83 - Simplify-isLapis-sentence-card-field-config-to-fixed-field-names.md b/backlog/tasks/task-83 - Simplify-isLapis-sentence-card-field-config-to-fixed-field-names.md new file mode 100644 index 0000000..28c8888 --- /dev/null +++ b/backlog/tasks/task-83 - Simplify-isLapis-sentence-card-field-config-to-fixed-field-names.md @@ -0,0 +1,44 @@ +--- +id: TASK-83 +title: Simplify isLapis sentence card field config to fixed field names +status: Done +assignee: + - codex-main +created_date: '2026-02-19 08:38' +updated_date: '2026-02-19 08:40' +labels: + - config + - anki + - cleanup +dependencies: [] +priority: medium +--- + +## Description + + +Remove `sentenceCardSentenceField` and `sentenceCardAudioField` from the `ankiConnect.isLapis` config surface so Lapis mode always uses fixed field names `Sentence` and `SentenceAudio`. Update types/defaults/docs/examples and adjust integration code to stop reading those keys. + + +## Acceptance Criteria + +- [x] #1 `isLapis` config no longer exposes `sentenceCardSentenceField` or `sentenceCardAudioField` in types/defaults/examples/docs +- [x] #2 Anki integration uses fixed sentence-card field names `Sentence` and `SentenceAudio` when Lapis/Kiku sentence-card flow runs +- [x] #3 Project build and relevant tests pass after removal + + +## Implementation Notes + + +Removed `sentenceCardSentenceField` and `sentenceCardAudioField` from `isLapis` config types/defaults (`src/types.ts`, `src/config/definitions.ts`). + +Updated Anki integration to always use fixed sentence-card field names `Sentence` and `SentenceAudio` in effective sentence-card config (`src/anki-integration.ts`). + +Hardened config resolution for `ankiConnect.isLapis` to only read `enabled` and `sentenceCardModel`, and emit warnings when deprecated sentence/audio field override keys are provided (`src/config/service.ts`). + +Updated examples/docs to remove the two keys and document fixed mapping (`config.example.jsonc`, `docs/public/config.example.jsonc`, `docs/configuration.md`, `docs/anki-integration.md`, `docs/mining-workflow.md`). + +Added regression coverage `ignores deprecated isLapis sentence-card field overrides` in `src/config/config.test.ts`. + +Verification: `bun run build && bun run test:config:dist` passed (33/33). + diff --git a/docs/anki-integration.md b/docs/anki-integration.md index b1e97d4..51a0e8f 100644 --- a/docs/anki-integration.md +++ b/docs/anki-integration.md @@ -159,9 +159,7 @@ SubMiner can create standalone sentence cards (without a word/expression) using "ankiConnect": { "isLapis": { "enabled": true, - "sentenceCardModel": "Japanese sentences", - "sentenceCardSentenceField": "Sentence", - "sentenceCardAudioField": "SentenceAudio" + "sentenceCardModel": "Japanese sentences" } } ``` @@ -254,8 +252,6 @@ When you mine the same word multiple times, SubMiner can merge the cards instead "isLapis": { "enabled": false, "sentenceCardModel": "Japanese sentences", - "sentenceCardSentenceField": "Sentence", - "sentenceCardAudioField": "SentenceAudio", }, }, } diff --git a/docs/configuration.md b/docs/configuration.md index 64d7f36..e93dae3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -139,9 +139,7 @@ Enable automatic Anki card creation and updates with media generation: }, "isLapis": { "enabled": true, - "sentenceCardModel": "Japanese sentences", - "sentenceCardSentenceField": "Sentence", - "sentenceCardAudioField": "SentenceAudio" + "sentenceCardModel": "Japanese sentences" }, "isKiku": { "enabled": false, @@ -204,7 +202,7 @@ This example is intentionally compact. The option table below documents availabl | `behavior.notificationType` | `"osd"`, `"system"`, `"both"`, `"none"` | Notification type on card update (default: `"osd"`) | | `behavior.autoUpdateNewCards` | `true`, `false` | Automatically update cards on creation (default: `true`) | | `metadata.pattern` | string | Format pattern for metadata: `%f`=filename, `%F`=filename+ext, `%t`=time | -| `isLapis` | object | Lapis/shared sentence-card config: `{ enabled, sentenceCardModel, sentenceCardSentenceField, sentenceCardAudioField }` | +| `isLapis` | object | Lapis/shared sentence-card config: `{ enabled, sentenceCardModel }`. Sentence/audio field names are fixed to `Sentence` and `SentenceAudio`. | | `isKiku` | object | Kiku-only config: `{ enabled, fieldGrouping, deleteDuplicateInAuto }` (shared sentence/audio/model settings are inherited from `isLapis`) | **Kiku / Lapis Note Type Support:** @@ -231,6 +229,7 @@ Known-word cache policy: - The cache is automatically invalidated when the configured scope changes (for example, when deck changes). - Cache lookups are in-memory. By default, token headwords are matched against cached `Expression` / `Word` values; set `ankiConnect.nPlusOne.matchMode` to `"surface"` for raw subtitle text matching. - `ankiConnect.behavior.nPlusOne*` legacy keys (`nPlusOneHighlightEnabled`, `nPlusOneRefreshMinutes`, `nPlusOneMatchMode`) are deprecated and only kept for backward compatibility. +- Legacy top-level `ankiConnect` migration keys (for example `audioField`, `generateAudio`, `imageType`) are compatibility-only, validated before mapping, and ignored with a warning when invalid. - If AnkiConnect is unreachable, the cache remains in its previous state and an on-screen/system status message is shown. - Known-word sync activity is logged at `INFO`/`DEBUG` level with the `anki` logger scope and includes scope, notes returned, and word counts. diff --git a/docs/mining-workflow.md b/docs/mining-workflow.md index c4fa353..089eae4 100644 --- a/docs/mining-workflow.md +++ b/docs/mining-workflow.md @@ -93,7 +93,7 @@ Create a standalone sentence card without going through Yomitan: - **Mine current sentence**: `Ctrl/Cmd+S` (configurable via `shortcuts.mineSentence`) - **Mine multiple lines**: `Ctrl/Cmd+Shift+S` followed by a digit 1–9 to select how many recent subtitle lines to combine. -The sentence card uses the note type configured in `isLapis.sentenceCardModel` with the sentence and audio fields mapped by `isLapis.sentenceCardSentenceField` and `isLapis.sentenceCardAudioField`. +The sentence card uses the note type configured in `isLapis.sentenceCardModel` and always maps sentence/audio to `Sentence` and `SentenceAudio`. ### 3. Mark as Audio Card diff --git a/src/anki-integration.ts b/src/anki-integration.ts index 4cba9d1..2444b9d 100644 --- a/src/anki-integration.ts +++ b/src/anki-integration.ts @@ -334,15 +334,11 @@ export class AnkiIntegration { private getLapisConfig(): { enabled: boolean; sentenceCardModel?: string; - sentenceCardSentenceField?: string; - sentenceCardAudioField?: string; } { const lapis = this.config.isLapis; return { enabled: lapis?.enabled === true, sentenceCardModel: lapis?.sentenceCardModel, - sentenceCardSentenceField: lapis?.sentenceCardSentenceField, - sentenceCardAudioField: lapis?.sentenceCardAudioField, }; } @@ -373,8 +369,8 @@ export class AnkiIntegration { return { model: lapis.sentenceCardModel, - sentenceField: lapis.sentenceCardSentenceField || 'Sentence', - audioField: lapis.sentenceCardAudioField || 'SentenceAudio', + sentenceField: 'Sentence', + audioField: 'SentenceAudio', lapisEnabled: lapis.enabled, kikuEnabled: kiku.enabled, kikuFieldGrouping: (kiku.fieldGrouping || 'disabled') as 'auto' | 'manual' | 'disabled', diff --git a/src/config/definitions.ts b/src/config/definitions.ts index 938c255..8921eb9 100644 --- a/src/config/definitions.ts +++ b/src/config/definitions.ts @@ -136,8 +136,6 @@ export const DEFAULT_CONFIG: ResolvedConfig = { isLapis: { enabled: false, sentenceCardModel: 'Japanese sentences', - sentenceCardSentenceField: 'Sentence', - sentenceCardAudioField: 'SentenceAudio', }, isKiku: { enabled: false, diff --git a/src/types.ts b/src/types.ts index 8f09e6b..b038112 100644 --- a/src/types.ts +++ b/src/types.ts @@ -260,8 +260,6 @@ export interface AnkiConnectConfig { isLapis?: { enabled?: boolean; sentenceCardModel?: string; - sentenceCardSentenceField?: string; - sentenceCardAudioField?: string; }; isKiku?: { enabled?: boolean; @@ -480,8 +478,6 @@ export interface ResolvedConfig { isLapis: { enabled: boolean; sentenceCardModel: string; - sentenceCardSentenceField: string; - sentenceCardAudioField: string; }; isKiku: { enabled: boolean;