qwerty-cli 0.0.1-alpha.4 → 0.0.1-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +62 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
2
|
import { Command as Command6 } from "commander";
|
|
3
3
|
|
|
4
|
+
// package.json
|
|
5
|
+
var package_default = {
|
|
6
|
+
name: "qwerty-cli",
|
|
7
|
+
version: "0.0.1-alpha.5",
|
|
8
|
+
description: "Terminal clone of qwerty-learner: typing practice for English vocabulary, with chapters, dictation, mistake book, and audio.",
|
|
9
|
+
type: "module",
|
|
10
|
+
bin: {
|
|
11
|
+
qwerty: "bin/qwerty.mjs"
|
|
12
|
+
},
|
|
13
|
+
files: [
|
|
14
|
+
"dist",
|
|
15
|
+
"bin",
|
|
16
|
+
"assets"
|
|
17
|
+
],
|
|
18
|
+
scripts: {
|
|
19
|
+
build: "tsup",
|
|
20
|
+
dev: "tsup --watch",
|
|
21
|
+
typecheck: "tsc --noEmit",
|
|
22
|
+
test: "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"sync-registry": "tsx scripts/sync-registry.ts",
|
|
25
|
+
prepublishOnly: "pnpm build"
|
|
26
|
+
},
|
|
27
|
+
engines: {
|
|
28
|
+
node: ">=20"
|
|
29
|
+
},
|
|
30
|
+
keywords: [
|
|
31
|
+
"qwerty",
|
|
32
|
+
"typing",
|
|
33
|
+
"cli",
|
|
34
|
+
"vocabulary",
|
|
35
|
+
"ink",
|
|
36
|
+
"terminal"
|
|
37
|
+
],
|
|
38
|
+
license: "MIT",
|
|
39
|
+
dependencies: {
|
|
40
|
+
chalk: "^5.3.0",
|
|
41
|
+
commander: "^12.1.0",
|
|
42
|
+
ink: "^5.0.1",
|
|
43
|
+
"ink-big-text": "^2.0.0",
|
|
44
|
+
"p-queue": "^8.0.1",
|
|
45
|
+
react: "^18.3.1",
|
|
46
|
+
undici: "^6.19.8",
|
|
47
|
+
zod: "^3.23.8"
|
|
48
|
+
},
|
|
49
|
+
devDependencies: {
|
|
50
|
+
"@types/node": "^20.14.10",
|
|
51
|
+
"@types/react": "^18.3.3",
|
|
52
|
+
"ts-morph": "^23.0.0",
|
|
53
|
+
tsup: "^8.2.4",
|
|
54
|
+
tsx: "^4.19.0",
|
|
55
|
+
typescript: "^5.5.4",
|
|
56
|
+
vitest: "^2.0.5"
|
|
57
|
+
},
|
|
58
|
+
pnpm: {
|
|
59
|
+
onlyBuiltDependencies: [
|
|
60
|
+
"esbuild"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
4
65
|
// src/commands/config.ts
|
|
5
66
|
import { Command } from "commander";
|
|
6
67
|
import chalk from "chalk";
|
|
@@ -2390,7 +2451,7 @@ async function runMainMenu() {
|
|
|
2390
2451
|
|
|
2391
2452
|
// src/cli.ts
|
|
2392
2453
|
var program = new Command6();
|
|
2393
|
-
program.name("qwerty").description("Terminal clone of qwerty-learner \u2014 typing practice for English vocabulary").version(
|
|
2454
|
+
program.name("qwerty").description("Terminal clone of qwerty-learner \u2014 typing practice for English vocabulary").version(package_default.version);
|
|
2394
2455
|
program.addCommand(buildPracticeCommand());
|
|
2395
2456
|
program.addCommand(buildDictCommand());
|
|
2396
2457
|
program.addCommand(buildWordCommand());
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/config.ts","../src/infra/config-store.ts","../src/infra/paths.ts","../src/infra/fs-store.ts","../src/commands/dict.ts","../src/domain/dictionary.ts","../src/infra/registry-store.ts","../src/infra/dict-downloader.ts","../src/commands/practice.ts","../src/ui/App.tsx","../src/ui/nav.tsx","../src/ui/Fullscreen.tsx","../src/ui/audio-context.tsx","../src/infra/audio.ts","../src/ui/app-state.tsx","../src/ui/screens/MainMenu.tsx","../src/ui/components/BigWord.tsx","../src/ui/screens/PracticeScreen.tsx","../src/util/shuffle.ts","../src/domain/chapters.ts","../src/domain/input-buffer.ts","../src/domain/session.ts","../src/domain/mistakes.ts","../src/ui/hooks/useWordLoop.ts","../src/ui/hooks/useAudio.ts","../src/ui/hooks/useSessionPersistence.ts","../src/domain/stats.ts","../src/ui/screens/DictBrowser.tsx","../src/ui/screens/ConfigEditor.tsx","../src/ui/screens/StatsViewer.tsx","../src/ui/screens/WordLookup.tsx","../src/commands/stats.ts","../src/commands/word.ts","../src/commands/menu.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { buildConfigCommand } from './commands/config.js';\nimport { buildDictCommand } from './commands/dict.js';\nimport { buildPracticeCommand } from './commands/practice.js';\nimport { buildStatsCommand } from './commands/stats.js';\nimport { buildWordCommand } from './commands/word.js';\nimport { runMainMenu } from './commands/menu.js';\n\nconst program = new Command();\n\nprogram\n .name('qwerty')\n .description('Terminal clone of qwerty-learner — typing practice for English vocabulary')\n .version('0.1.0');\n\nprogram.addCommand(buildPracticeCommand());\nprogram.addCommand(buildDictCommand());\nprogram.addCommand(buildWordCommand());\nprogram.addCommand(buildStatsCommand());\nprogram.addCommand(buildConfigCommand());\n\nprogram.action(async () => {\n await runMainMenu();\n});\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig, saveConfig, getByPath, setByPath } from '../infra/config-store.js';\n\nexport function buildConfigCommand(): Command {\n const cmd = new Command('config').description('Manage CLI configuration');\n\n cmd\n .command('list')\n .description('Show the effective merged config')\n .action(async () => {\n const cfg = await loadConfig();\n console.log(JSON.stringify(cfg, null, 2));\n });\n\n cmd\n .command('get <key>')\n .description('Get a config value by dotted path (e.g. sounds.keystroke)')\n .action(async (key: string) => {\n const cfg = await loadConfig();\n const v = getByPath(cfg, key);\n if (v === undefined) {\n console.error(chalk.red(`Key not found: ${key}`));\n process.exitCode = 1;\n return;\n }\n console.log(typeof v === 'string' ? v : JSON.stringify(v));\n });\n\n cmd\n .command('set <key> <value>')\n .description('Set a config value by dotted path')\n .action(async (key: string, value: string) => {\n const cfg = await loadConfig();\n const next = setByPath(cfg, key, value);\n await saveConfig(next);\n console.log(chalk.green(`Set ${key} = ${value}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { paths } from './paths.js';\nimport { readJson, writeJsonAtomic } from './fs-store.js';\n\nexport const ConfigSchema = z.object({\n mirror: z.enum(['jsdelivr', 'github']).default('jsdelivr'),\n accent: z.enum(['us', 'uk']).default('us'),\n chapterSize: z.number().int().positive().max(200).default(20),\n sounds: z\n .object({\n master: z.boolean().default(true),\n keystroke: z.boolean().default(true),\n feedback: z.boolean().default(true),\n keySoundName: z.string().default('default'),\n })\n .default({ master: true, keystroke: true, feedback: true, keySoundName: 'default' }),\n autoplayPronunciation: z.boolean().default(true),\n defaultMode: z.enum(['order', 'dictation', 'review', 'random', 'loop']).default('order'),\n defaultDict: z.string().optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nconst DEFAULTS: Config = ConfigSchema.parse({});\n\nexport async function loadConfig(): Promise<Config> {\n const raw = await readJson<unknown>(paths.config);\n if (!raw) return DEFAULTS;\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid config at ${paths.config}: ${result.error.message}`);\n }\n return result.data;\n}\n\nexport async function saveConfig(cfg: Config): Promise<void> {\n await writeJsonAtomic(paths.config, cfg);\n}\n\nexport function getByPath(cfg: Config, path: string): unknown {\n const parts = path.split('.');\n let cur: unknown = cfg;\n for (const p of parts) {\n if (cur === null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nexport function setByPath(cfg: Config, path: string, rawValue: string): Config {\n const parts = path.split('.');\n if (parts.length === 0) throw new Error('Empty config key');\n const clone: Record<string, unknown> = JSON.parse(JSON.stringify(cfg));\n let cur: Record<string, unknown> = clone;\n for (let i = 0; i < parts.length - 1; i++) {\n const k = parts[i]!;\n const next = cur[k];\n if (typeof next !== 'object' || next === null) {\n throw new Error(`Cannot set ${path}: ${parts.slice(0, i + 1).join('.')} is not an object`);\n }\n cur = next as Record<string, unknown>;\n }\n const leaf = parts[parts.length - 1]!;\n cur[leaf] = coerce(rawValue);\n const validated = ConfigSchema.safeParse(clone);\n if (!validated.success) {\n throw new Error(`Invalid value for ${path}: ${validated.error.issues[0]?.message ?? 'unknown'}`);\n }\n return validated.data;\n}\n\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v === 'null') return null;\n if (/^-?\\d+$/.test(v)) return Number(v);\n if (/^-?\\d+\\.\\d+$/.test(v)) return Number(v);\n return v;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\n\nconst ROOT = join(homedir(), '.qwerty-cli');\n\nexport const paths = {\n root: ROOT,\n config: join(ROOT, 'config.json'),\n registry: join(ROOT, 'registry.json'),\n dictsDir: join(ROOT, 'dicts'),\n dictFile: (id: string) => join(ROOT, 'dicts', `${id}.json`),\n dictMeta: (id: string) => join(ROOT, 'dicts', `${id}.meta.json`),\n stats: join(ROOT, 'stats.jsonl'),\n mistakes: join(ROOT, 'mistakes.json'),\n audioCacheDir: join(ROOT, 'cache', 'audio'),\n audioCache: (word: string, accent: 'us' | 'uk') =>\n join(ROOT, 'cache', 'audio', `${encodeURIComponent(word.toLowerCase())}-${accent}.mp3`),\n};\n\nexport async function ensureDirs(): Promise<void> {\n await mkdir(paths.dictsDir, { recursive: true });\n await mkdir(paths.audioCacheDir, { recursive: true });\n}\n\nexport function packageAssetsDir(): string {\n // Works for both bundled (dist/cli.js) and source (src/infra/paths.ts) layouts:\n // 2 levels up from this file lands at the package root.\n const here = fileURLToPath(import.meta.url);\n return resolve(here, '..', '..', 'assets');\n}\n","import { mkdir, readFile, rename, writeFile, appendFile, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJson<T>(path: string): Promise<T | null> {\n try {\n const buf = await readFile(path, 'utf8');\n return JSON.parse(buf) as T;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\nexport async function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n await writeFile(tmp, JSON.stringify(value, null, 2), 'utf8');\n await rename(tmp, path);\n}\n\nexport async function appendJsonl(path: string, line: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(line) + '\\n', 'utf8');\n}\n\nexport async function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const buf = await readFile(path, 'utf8');\n return buf\n .split('\\n')\n .filter((l) => l.trim().length > 0)\n .map((l) => JSON.parse(l) as T);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { filterRegistry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { loadRegistry } from '../infra/registry-store.js';\nimport {\n pullDictionary,\n importDictionary,\n isLocallyAvailable,\n removeDictionary,\n} from '../infra/dict-downloader.js';\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nasync function renderTable(entries: DictionaryEntry[]): Promise<void> {\n const flagged = await Promise.all(\n entries.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n const widths = {\n local: 3,\n id: Math.max(2, ...flagged.map((f) => f.entry.id.length)),\n name: Math.max(4, ...flagged.map((f) => f.entry.name.length)),\n category: Math.max(8, ...flagged.map((f) => f.entry.category.length)),\n length: Math.max(5, ...flagged.map((f) => String(f.entry.length).length)),\n };\n const pad = (s: string, n: number) => s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n const header = [\n pad(' ', widths.local),\n chalk.bold(pad('ID', widths.id)),\n chalk.bold(pad('Name', widths.name)),\n chalk.bold(pad('Category', widths.category)),\n chalk.bold(pad('Words', widths.length)),\n chalk.bold('Description'),\n ].join(' ');\n console.log(header);\n for (const { entry, local } of flagged) {\n const mark = local ? chalk.green(' ✓') : ' ';\n console.log(\n [\n pad(mark, widths.local),\n pad(entry.id, widths.id),\n pad(entry.name, widths.name),\n chalk.dim(pad(entry.category, widths.category)),\n pad(String(entry.length), widths.length),\n chalk.dim(entry.description),\n ].join(' '),\n );\n }\n}\n\n// Naive: count CJK as width-2 for alignment.\nfunction visibleWidth(s: string): number {\n let w = 0;\n // strip ansi\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, '');\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function buildDictCommand(): Command {\n const cmd = new Command('dict').description('Manage dictionaries');\n\n cmd\n .command('list')\n .description('List dictionaries (✓ = locally available)')\n .option('-c, --category <category>', 'filter by category')\n .option('--local-only', 'show only locally downloaded dictionaries')\n .action(async (opts: { category?: string; localOnly?: boolean }) => {\n const reg = await loadRegistry();\n let entries = opts.category\n ? reg.filter((e) => e.category === opts.category)\n : reg;\n if (opts.localOnly) {\n const flags = await Promise.all(entries.map((e) => isLocallyAvailable(e.id)));\n entries = entries.filter((_, i) => flags[i]);\n }\n await renderTable(entries);\n console.log(chalk.dim(`\\n${entries.length} dictionaries`));\n });\n\n cmd\n .command('search <keyword>')\n .description('Search the upstream registry by name/description/category/tags')\n .option('-c, --category <category>', 'restrict to category')\n .option('-l, --language <language>', 'restrict to language')\n .action(async (keyword: string, opts: { category?: string; language?: string }) => {\n const reg = await loadRegistry();\n const matches = filterRegistry(reg, keyword, opts);\n if (matches.length === 0) {\n console.log(chalk.yellow(`No dictionaries matched \"${keyword}\"`));\n return;\n }\n await renderTable(matches);\n console.log(chalk.dim(`\\n${matches.length} matches`));\n });\n\n cmd\n .command('pull <id>')\n .description('Download an upstream dictionary into the local cache')\n .action(async (id: string) => {\n try {\n const { words, size } = await pullDictionary(id);\n console.log(chalk.green(`Saved ${words.length} words (${fmtBytes(size)}) → dict ${chalk.bold(id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('import <file>')\n .description('Import a local qwerty-native JSON dictionary')\n .requiredOption('--id <id>', 'dictionary id (lowercase, digits, dashes)')\n .action(async (file: string, opts: { id: string }) => {\n try {\n const { words, size } = await importDictionary(file, opts.id);\n console.log(chalk.green(`Imported ${words.length} words (${fmtBytes(size)}) as ${chalk.bold(opts.id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('rm <id>')\n .description('Remove a local dictionary')\n .action(async (id: string) => {\n const removed = await removeDictionary(id);\n if (removed) console.log(chalk.green(`Removed ${id}`));\n else console.log(chalk.yellow(`Nothing to remove for ${id}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\n\nexport const DictionaryEntrySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().default(''),\n category: z.string().default(''),\n tags: z.array(z.string()).default([]),\n url: z.string(),\n length: z.number().int().nonnegative().default(0),\n language: z.string().default('en'),\n languageCategory: z.string().default('en'),\n defaultPronIndex: z.number().int().optional(),\n});\n\nexport type DictionaryEntry = z.infer<typeof DictionaryEntrySchema>;\n\nexport const RegistrySchema = z.array(DictionaryEntrySchema);\nexport type Registry = DictionaryEntry[];\n\nexport const WordSchema = z\n .object({\n name: z.string(),\n trans: z.array(z.string()).default([]),\n usphone: z.string().optional(),\n ukphone: z.string().optional(),\n notation: z.string().optional(),\n })\n .passthrough();\n\nexport type Word = z.infer<typeof WordSchema>;\n\nexport const WordArraySchema = z.array(WordSchema);\n\nexport function filterRegistry(\n registry: Registry,\n query: string,\n opts: { category?: string; language?: string } = {},\n): Registry {\n const q = query.trim().toLowerCase();\n return registry.filter((d) => {\n if (opts.category && d.category !== opts.category) return false;\n if (opts.language && d.language !== opts.language) return false;\n if (!q) return true;\n return (\n d.id.toLowerCase().includes(q) ||\n d.name.toLowerCase().includes(q) ||\n d.description.toLowerCase().includes(q) ||\n d.category.toLowerCase().includes(q) ||\n d.tags.some((t) => t.toLowerCase().includes(q))\n );\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { RegistrySchema, type Registry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, packageAssetsDir } from './paths.js';\nimport { readJson } from './fs-store.js';\n\nlet cached: Registry | null = null;\n\nexport async function loadRegistry(): Promise<Registry> {\n if (cached) return cached;\n\n const userOverride = await readJson<unknown>(paths.registry);\n if (userOverride) {\n const parsed = RegistrySchema.safeParse(userOverride);\n if (parsed.success) {\n cached = parsed.data;\n return cached;\n }\n console.warn(`Ignoring corrupt user registry at ${paths.registry}: ${parsed.error.message}`);\n }\n\n const bundled = await readFile(join(packageAssetsDir(), 'registry.snapshot.json'), 'utf8');\n const parsed = RegistrySchema.parse(JSON.parse(bundled));\n cached = parsed;\n return cached;\n}\n\nexport async function findEntry(id: string): Promise<DictionaryEntry | undefined> {\n const reg = await loadRegistry();\n return reg.find((d) => d.id === id);\n}\n","import { createHash } from 'node:crypto';\nimport { stat, copyFile } from 'node:fs/promises';\nimport { request } from 'undici';\nimport { WordArraySchema, type Word, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, ensureDirs } from './paths.js';\nimport { exists, readJson, writeJsonAtomic } from './fs-store.js';\nimport { findEntry } from './registry-store.js';\nimport { loadConfig } from './config-store.js';\n\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/RealKai42/qwerty-learner@master';\nconst GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/RealKai42/qwerty-learner/master';\n\ntype Meta = { sha256: string; size: number; fetchedAt: string; id: string };\n\nasync function fetchWithRetry(url: string, retries = 2): Promise<string> {\n let lastErr: unknown;\n for (let i = 0; i <= retries; i++) {\n try {\n const res = await request(url, { headersTimeout: 10000, bodyTimeout: 30000 });\n if (res.statusCode >= 400) throw new Error(`HTTP ${res.statusCode}`);\n return await res.body.text();\n } catch (err) {\n lastErr = err;\n if (i < retries) await new Promise((r) => setTimeout(r, 500 * (i + 1)));\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n}\n\nfunction buildUrls(mirror: 'jsdelivr' | 'github', relUrl: string): string[] {\n // Registry urls are web-relative (\"/dicts/X.json\"); upstream repo serves them\n // from /public/, so prepend that prefix when hitting source mirrors.\n const path = relUrl.startsWith('/') ? relUrl : `/${relUrl}`;\n const repoPath = `/public${path}`;\n const jsd = `${JSDELIVR_BASE}${repoPath}`;\n const gh = `${GITHUB_RAW_BASE}${repoPath}`;\n return mirror === 'jsdelivr' ? [jsd, gh] : [gh, jsd];\n}\n\nexport async function pullDictionary(id: string): Promise<{ words: Word[]; size: number }> {\n const entry = await findEntry(id);\n if (!entry) throw new Error(`Unknown dictionary id: ${id}`);\n const cfg = await loadConfig();\n await ensureDirs();\n\n const urls = buildUrls(cfg.mirror, entry.url);\n let body: string | null = null;\n let lastErr: unknown;\n for (const u of urls) {\n try {\n body = await fetchWithRetry(u);\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!body) {\n throw new Error(\n `Failed to download dictionary ${id} from any mirror: ${lastErr instanceof Error ? lastErr.message : lastErr}`,\n );\n }\n\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch (err) {\n throw new Error(`Dictionary ${id} is not valid JSON: ${(err as Error).message}`);\n }\n\n const parsed = WordArraySchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(`Dictionary ${id} failed schema validation: ${parsed.error.issues[0]?.message}`);\n }\n\n const sha = createHash('sha256').update(body).digest('hex');\n await writeJsonAtomic(paths.dictFile(id), parsed.data);\n const meta: Meta = { sha256: sha, size: body.length, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size: body.length };\n}\n\nexport async function importDictionary(file: string, id: string): Promise<{ words: Word[]; size: number }> {\n if (!/^[a-z0-9-]+$/.test(id)) {\n throw new Error(`Invalid id \"${id}\". Must match /^[a-z0-9-]+$/`);\n }\n await ensureDirs();\n if (!(await exists(file))) throw new Error(`File not found: ${file}`);\n\n const raw = await readJson<unknown>(file);\n const parsed = WordArraySchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Import rejected: ${parsed.error.issues[0]?.message}`);\n }\n await copyFile(file, paths.dictFile(id));\n const size = (await stat(paths.dictFile(id))).size;\n const sha = createHash('sha256').update(JSON.stringify(parsed.data)).digest('hex');\n const meta: Meta = { sha256: sha, size, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size };\n}\n\nexport async function loadLocalDictionary(id: string): Promise<Word[] | null> {\n const data = await readJson<unknown>(paths.dictFile(id));\n if (!data) return null;\n const parsed = WordArraySchema.safeParse(data);\n if (!parsed.success) throw new Error(`Local dictionary ${id} corrupt: ${parsed.error.message}`);\n return parsed.data;\n}\n\nexport async function isLocallyAvailable(id: string): Promise<boolean> {\n return exists(paths.dictFile(id));\n}\n\nexport async function ensureDictionary(id: string): Promise<Word[]> {\n const local = await loadLocalDictionary(id);\n if (local) return local;\n const { words } = await pullDictionary(id);\n return words;\n}\n\nexport async function removeDictionary(id: string): Promise<boolean> {\n const { unlink } = await import('node:fs/promises');\n let removed = false;\n for (const p of [paths.dictFile(id), paths.dictMeta(id)]) {\n try {\n await unlink(p);\n removed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n return removed;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport type { Mode } from '../domain/chapters.js';\n\nconst MODES: Mode[] = ['order', 'dictation', 'review', 'random', 'loop'];\n\nfunction isMode(v: string): v is Mode {\n return (MODES as string[]).includes(v);\n}\n\nexport async function runPractice(\n dictIdArg: string | undefined,\n options: { chapter?: string | number; mode?: string },\n): Promise<void> {\n if (!process.stdout.isTTY) {\n console.error(chalk.red('Practice requires an interactive TTY.'));\n process.exitCode = 1;\n return;\n }\n const cfg = await loadConfig();\n const dictId = dictIdArg ?? cfg.defaultDict;\n if (!dictId) {\n console.error(chalk.red('No dictionary specified. Pass an id or set config.defaultDict.'));\n process.exitCode = 1;\n return;\n }\n const mode = options.mode ?? cfg.defaultMode;\n if (!isMode(mode)) {\n console.error(chalk.red(`Invalid mode \"${mode}\". Valid: ${MODES.join(', ')}`));\n process.exitCode = 1;\n return;\n }\n const chapterIndex = Math.max(0, Number(options.chapter ?? 1) - 1);\n\n const { waitUntilExit } = render(\n createElement(App, {\n initial: { name: 'practice', params: { dictId, chapterIndex, mode } },\n initialCfg: cfg,\n }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n}\n\nexport function buildPracticeCommand(): Command {\n return new Command('practice')\n .argument('[dictId]', 'dictionary id; falls back to config.defaultDict')\n .description('Start a typing practice session')\n .option('-c, --chapter <n>', 'chapter number (1-based)', '1')\n .option('-m, --mode <mode>', 'order | dictation | review | random | loop')\n .action(async (dictIdArg: string | undefined, options: { chapter: string; mode?: string }) => {\n await runPractice(dictIdArg, options);\n });\n}\n","import { useApp, useInput } from 'ink';\nimport { NavProvider, useNav, type ScreenFrame } from './nav.js';\nimport { Fullscreen } from './Fullscreen.js';\nimport { AudioStatusProvider } from './audio-context.js';\nimport { AppStateProvider, useAppState } from './app-state.js';\nimport { MainMenu } from './screens/MainMenu.js';\nimport { PracticeScreen } from './screens/PracticeScreen.js';\nimport { DictBrowser } from './screens/DictBrowser.js';\nimport { ConfigEditor } from './screens/ConfigEditor.js';\nimport { StatsViewer } from './screens/StatsViewer.js';\nimport { WordLookup } from './screens/WordLookup.js';\nimport type { Config } from '../infra/config-store.js';\n\nexport function App({ initial, initialCfg }: { initial: ScreenFrame; initialCfg: Config }) {\n return (\n <AppStateProvider initialCfg={initialCfg}>\n <AudioStatusProvider disabled={!initialCfg.sounds.master}>\n <NavProvider initial={initial}>\n <Fullscreen>\n <Router />\n </Fullscreen>\n </NavProvider>\n </AudioStatusProvider>\n </AppStateProvider>\n );\n}\n\nfunction Router() {\n const nav = useNav();\n const { cfg } = useAppState();\n const { exit } = useApp();\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') exit();\n });\n\n const frame = nav.current;\n switch (frame.name) {\n case 'main':\n return <MainMenu cfg={cfg} />;\n case 'practice':\n return <PracticeScreen params={frame.params} />;\n case 'dict':\n return <DictBrowser params={frame.params} />;\n case 'config':\n return <ConfigEditor />;\n case 'stats':\n return <StatsViewer />;\n case 'word':\n return <WordLookup />;\n }\n}\n","import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';\n\nexport type ScreenName =\n | 'main'\n | 'practice'\n | 'dict'\n | 'config'\n | 'stats'\n | 'word';\n\nexport type PracticeParams = {\n dictId: string;\n chapterIndex: number;\n mode: 'order' | 'dictation' | 'review' | 'random' | 'loop';\n};\n\nexport type DictParams = {\n pickerMode?: 'set-default' | 'choose-then-practice';\n};\n\nexport type ScreenFrame =\n | { name: 'main' }\n | { name: 'practice'; params: PracticeParams }\n | { name: 'dict'; params?: DictParams }\n | { name: 'config' }\n | { name: 'stats' }\n | { name: 'word' };\n\ntype NavContextValue = {\n current: ScreenFrame;\n stack: ScreenFrame[];\n navigate: (frame: ScreenFrame) => void;\n replace: (frame: ScreenFrame) => void;\n back: () => void;\n reset: (frame: ScreenFrame) => void;\n};\n\nconst NavContext = createContext<NavContextValue | null>(null);\n\nexport function NavProvider({ initial, children }: { initial: ScreenFrame; children: ReactNode }) {\n const [stack, setStack] = useState<ScreenFrame[]>([initial]);\n\n const navigate = useCallback((frame: ScreenFrame) => {\n setStack((s) => [...s, frame]);\n }, []);\n const replace = useCallback((frame: ScreenFrame) => {\n setStack((s) => (s.length === 0 ? [frame] : [...s.slice(0, -1), frame]));\n }, []);\n const back = useCallback(() => {\n setStack((s) => (s.length > 1 ? s.slice(0, -1) : s));\n }, []);\n const reset = useCallback((frame: ScreenFrame) => {\n setStack([frame]);\n }, []);\n\n const current = stack[stack.length - 1]!;\n return (\n <NavContext.Provider value={{ current, stack, navigate, replace, back, reset }}>\n {children}\n </NavContext.Provider>\n );\n}\n\nexport function useNav(): NavContextValue {\n const ctx = useContext(NavContext);\n if (!ctx) throw new Error('useNav must be used inside NavProvider');\n return ctx;\n}\n","import { useEffect, type ReactNode } from 'react';\n\nconst ENTER = '\\x1b[?1049h\\x1b[?25l';\nconst LEAVE = '\\x1b[?25h\\x1b[?1049l';\n\nfunction shouldUse(): boolean {\n return Boolean(process.stdout.isTTY) && process.env.QWERTY_NO_ALTSCREEN !== '1';\n}\n\nexport function Fullscreen({ children }: { children: ReactNode }) {\n useEffect(() => {\n if (!shouldUse()) return;\n process.stdout.write(ENTER);\n\n const leave = () => {\n try {\n process.stdout.write(LEAVE);\n } catch {\n // stream may already be closed\n }\n };\n\n const onSignal = () => {\n leave();\n process.exit(130);\n };\n\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', leave);\n\n return () => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n process.off('exit', leave);\n leave();\n };\n }, []);\n\n return <>{children}</>;\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { initAudio, audioWarning } from '../infra/audio.js';\n\ntype AudioStatus = { warning: string | null; ready: boolean };\n\nconst AudioStatusContext = createContext<AudioStatus>({ warning: null, ready: false });\n\nexport function AudioStatusProvider({\n disabled,\n children,\n}: {\n disabled: boolean;\n children: ReactNode;\n}) {\n const [status, setStatus] = useState<AudioStatus>({ warning: null, ready: false });\n\n useEffect(() => {\n let cancelled = false;\n initAudio(disabled)\n .then(() => {\n if (cancelled) return;\n setStatus({ warning: audioWarning(), ready: true });\n })\n .catch(() => {\n if (cancelled) return;\n setStatus({ warning: null, ready: true });\n });\n return () => {\n cancelled = true;\n };\n }, [disabled]);\n\n return <AudioStatusContext.Provider value={status}>{children}</AudioStatusContext.Provider>;\n}\n\nexport function useAudioStatus(): AudioStatus {\n return useContext(AudioStatusContext);\n}\n","import { spawn } from 'node:child_process';\nimport { access, mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { request } from 'undici';\nimport PQueue from 'p-queue';\nimport { paths, packageAssetsDir, ensureDirs } from './paths.js';\nimport { exists } from './fs-store.js';\n\ntype PlayerKind = 'afplay' | 'paplay' | 'aplay' | 'mpg123' | 'ffplay' | 'powershell';\n\ntype Player = {\n kind: PlayerKind;\n cmd: string;\n args: (file: string) => string[];\n supports: 'wav' | 'mp3' | 'both';\n};\n\nconst CANDIDATES: Player[] = [\n { kind: 'afplay', cmd: 'afplay', args: (f) => [f], supports: 'both' },\n { kind: 'ffplay', cmd: 'ffplay', args: (f) => ['-nodisp', '-autoexit', '-loglevel', 'quiet', f], supports: 'both' },\n { kind: 'mpg123', cmd: 'mpg123', args: (f) => ['-q', f], supports: 'mp3' },\n { kind: 'paplay', cmd: 'paplay', args: (f) => [f], supports: 'wav' },\n { kind: 'aplay', cmd: 'aplay', args: (f) => ['-q', f], supports: 'wav' },\n {\n kind: 'powershell',\n cmd: 'powershell',\n args: (f) => ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${f}').PlaySync();`],\n supports: 'wav',\n },\n];\n\nconst PRON_API = 'https://dict.youdao.com/dictvoice?audio=';\n\ntype AudioRuntime = {\n disabled: boolean;\n wavPlayer: Player | null;\n mp3Player: Player | null;\n warning: string | null;\n keyQueue: PQueue;\n feedbackQueue: PQueue;\n pronQueue: PQueue;\n};\n\nlet runtime: AudioRuntime | null = null;\n\nasync function isExecutable(cmd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const probe = spawn(cmd, ['--version'], { stdio: 'ignore' });\n probe.on('error', () => resolve(false));\n probe.on('exit', () => resolve(true));\n setTimeout(() => {\n probe.kill();\n resolve(false);\n }, 500);\n });\n}\n\nasync function detect(): Promise<{ wav: Player | null; mp3: Player | null }> {\n let wav: Player | null = null;\n let mp3: Player | null = null;\n for (const p of CANDIDATES) {\n if (!(await isExecutable(p.cmd))) continue;\n if (!wav && (p.supports === 'wav' || p.supports === 'both')) wav = p;\n if (!mp3 && (p.supports === 'mp3' || p.supports === 'both')) mp3 = p;\n if (wav && mp3) break;\n }\n return { wav, mp3 };\n}\n\nexport async function initAudio(disabledByConfig: boolean): Promise<AudioRuntime> {\n if (runtime) return runtime;\n if (disabledByConfig) {\n runtime = {\n disabled: true,\n wavPlayer: null,\n mp3Player: null,\n warning: null,\n keyQueue: new PQueue({ concurrency: 1 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n }\n const { wav, mp3 } = await detect();\n let warning: string | null = null;\n if (!wav && !mp3) {\n warning = 'No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.';\n } else if (!mp3) {\n warning = 'No MP3 player found; word pronunciations will be skipped.';\n }\n runtime = {\n disabled: !wav && !mp3,\n wavPlayer: wav,\n mp3Player: mp3,\n warning,\n keyQueue: new PQueue({ concurrency: 2 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n}\n\nfunction spawnPlay(player: Player, file: string): void {\n try {\n const child = spawn(player.cmd, player.args(file), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => {\n // swallow; runtime will be disabled if many failures stack up\n });\n child.unref();\n } catch {\n /* fail-soft */\n }\n}\n\nfunction playFile(file: string, kind: 'wav' | 'mp3'): void {\n if (!runtime || runtime.disabled) return;\n const player = kind === 'wav' ? runtime.wavPlayer : runtime.mp3Player;\n if (!player) return;\n spawnPlay(player, file);\n}\n\nexport function playKeystroke(): void {\n if (!runtime || runtime.disabled) return;\n // Drop if queue is saturated; we never want to delay typing.\n if (runtime.keyQueue.size >= 2) return;\n void runtime.keyQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'key-default.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 30));\n });\n}\n\nexport function playCorrect(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'correct.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nexport function playWrong(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'wrong.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nasync function downloadPronunciation(word: string, accent: 'us' | 'uk'): Promise<string | null> {\n const cacheFile = paths.audioCache(word, accent);\n if (await exists(cacheFile)) return cacheFile;\n await mkdir(dirname(cacheFile), { recursive: true });\n const type = accent === 'us' ? 2 : 1;\n const url = `${PRON_API}${encodeURIComponent(word)}&type=${type}`;\n try {\n const res = await request(url, { headersTimeout: 8000, bodyTimeout: 20000 });\n if (res.statusCode >= 400) return null;\n const buf = Buffer.from(await res.body.arrayBuffer());\n if (buf.length < 1024) return null;\n const tmp = `${cacheFile}.tmp`;\n await writeFile(tmp, buf);\n await rename(tmp, cacheFile);\n return cacheFile;\n } catch {\n return null;\n }\n}\n\nexport async function playPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n await runtime.pronQueue.add(async () => {\n const file = await downloadPronunciation(word, accent);\n if (file) playFile(file, 'mp3');\n });\n}\n\nexport async function prefetchPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n void runtime.pronQueue.add(async () => {\n await downloadPronunciation(word, accent);\n });\n}\n\nexport function audioWarning(): string | null {\n return runtime?.warning ?? null;\n}\n\nexport function audioDisabled(): boolean {\n return runtime?.disabled ?? true;\n}\n","import { createContext, useCallback, useContext, useState, type ReactNode } from 'react';\nimport { saveConfig as persistConfig, type Config } from '../infra/config-store.js';\n\ntype AppState = {\n cfg: Config;\n setCfg: (next: Config) => Promise<void>;\n};\n\nconst AppStateContext = createContext<AppState | null>(null);\n\nexport function AppStateProvider({\n initialCfg,\n children,\n}: {\n initialCfg: Config;\n children: ReactNode;\n}) {\n const [cfg, setCfgState] = useState<Config>(initialCfg);\n const setCfg = useCallback(async (next: Config) => {\n setCfgState(next);\n await persistConfig(next);\n }, []);\n return <AppStateContext.Provider value={{ cfg, setCfg }}>{children}</AppStateContext.Provider>;\n}\n\nexport function useAppState(): AppState {\n const ctx = useContext(AppStateContext);\n if (!ctx) throw new Error('useAppState must be used inside AppStateProvider');\n return ctx;\n}\n","import { useState } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAudioStatus } from '../audio-context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport type { Config } from '../../infra/config-store.js';\n\ntype Item = { key: string; label: string; hint: string; run: () => void };\n\nexport function MainMenu({ cfg }: { cfg: Config }) {\n const [selected, setSelected] = useState(0);\n const { exit } = useApp();\n const nav = useNav();\n const audio = useAudioStatus();\n\n const items: Item[] = [\n {\n key: 'p',\n label: 'Practice',\n hint: cfg.defaultDict ? `start ${cfg.defaultDict}` : 'pick a dictionary',\n run: () => {\n if (cfg.defaultDict) {\n nav.navigate({\n name: 'practice',\n params: { dictId: cfg.defaultDict, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.navigate({ name: 'dict', params: { pickerMode: 'choose-then-practice' } });\n }\n },\n },\n { key: 'd', label: 'Dictionaries', hint: 'browse, pull, set default', run: () => nav.navigate({ name: 'dict' }) },\n { key: 'w', label: 'Word lookup', hint: 'search local dicts', run: () => nav.navigate({ name: 'word' }) },\n { key: 's', label: 'Stats', hint: 'history & trends', run: () => nav.navigate({ name: 'stats' }) },\n { key: 'c', label: 'Config', hint: 'edit preferences', run: () => nav.navigate({ name: 'config' }) },\n { key: 'q', label: 'Quit', hint: 'Ctrl+C also exits', run: () => exit() },\n ];\n\n useInput((input, key) => {\n if (key.upArrow) setSelected((i) => (i - 1 + items.length) % items.length);\n if (key.downArrow) setSelected((i) => (i + 1) % items.length);\n if (key.return) {\n items[selected]!.run();\n return;\n }\n for (const it of items) {\n if (input === it.key) {\n it.run();\n return;\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n qwerty\n </Text>\n <Text color={PALETTE.muted}> · typing practice for the terminal</Text>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n {items.map((it, i) => {\n const active = i === selected;\n return (\n <Box key={it.key}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>[{it.key}]</Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {it.label.padEnd(14)}\n </Text>\n <Text color={PALETTE.muted}>{it.hint}</Text>\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n default dict: {cfg.defaultDict ?? '(none — pick one in Dictionaries)'}\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>↑/↓ navigate · Enter select · letters jump</Text>\n </Box>\n\n {audio.warning && (\n <Box marginTop={1}>\n <Text color={PALETTE.warning}>! {audio.warning}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { Box, Text, useStdout } from 'ink';\nimport BigText from 'ink-big-text';\n\nexport const PALETTE = {\n accent: '#5eead4',\n muted: '#6b7280',\n text: '#e5e7eb',\n primary: '#7dcfff',\n success: '#86efac',\n warning: '#fbbf24',\n error: '#f87171',\n} as const;\n\ntype Props = {\n target: string;\n typed: string;\n error?: boolean;\n hideTarget?: boolean;\n};\n\nexport function BigWord({ target, typed, error = false, hideTarget = false }: Props) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const chars = [...target];\n const typedChars = [...typed];\n\n const useBig = cols >= 60 && process.env.QWERTY_NO_BIGTEXT !== '1';\n\n if (!useBig) {\n return (\n <Box justifyContent=\"center\">\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = isTyped\n ? PALETTE.accent\n : error\n ? PALETTE.error\n : PALETTE.muted;\n return (\n <Text key={i} bold={isTyped} color={color} underline={!isTyped && error}>\n {display}{' '}\n </Text>\n );\n })}\n </Box>\n );\n }\n\n return (\n <Box justifyContent=\"center\" flexDirection=\"row\">\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = isTyped\n ? PALETTE.accent\n : error\n ? PALETTE.error\n : PALETTE.muted;\n return <BigText key={i} text={display} font=\"tiny\" colors={[color]} space={false} />;\n })}\n </Box>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport BigText from 'ink-big-text';\nimport type { Word } from '../../domain/dictionary.js';\nimport type { Mode } from '../../domain/chapters.js';\nimport { chunkChapters, buildPlaylist } from '../../domain/chapters.js';\nimport { sessionSummary } from '../../domain/session.js';\nimport { loadMistakes } from '../../domain/mistakes.js';\nimport { ensureDictionary } from '../../infra/dict-downloader.js';\nimport { useWordLoop } from '../hooks/useWordLoop.js';\nimport { useAudio } from '../hooks/useAudio.js';\nimport { useSessionPersistence } from '../hooks/useSessionPersistence.js';\nimport { useNav, type PracticeParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { BigWord, PALETTE } from '../components/BigWord.js';\n\ntype Phase = 'loading' | 'typing' | 'paused' | 'summary' | 'error';\n\ntype Loaded = {\n playlist: Word[];\n totalChapters: number;\n};\n\nexport function PracticeScreen({ params }: { params: PracticeParams }) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const nav = useNav();\n\n const [phase, setPhase] = useState<Phase>('loading');\n const [loaded, setLoaded] = useState<Loaded | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setPhase('loading');\n setLoaded(null);\n setErrorMsg(null);\n (async () => {\n try {\n const words = await ensureDictionary(dictId);\n if (cancelled) return;\n if (mode === 'review') {\n const book = await loadMistakes();\n if (cancelled) return;\n const reviewWords = words.filter((w) => book[w.name]?.count).slice(0, cfg.chapterSize);\n if (reviewWords.length === 0) {\n setErrorMsg('No mistakes to review yet. Practice some chapters first.');\n setPhase('error');\n return;\n }\n setLoaded({ playlist: reviewWords, totalChapters: 1 });\n setPhase('typing');\n return;\n }\n const chapters = chunkChapters(words, cfg.chapterSize);\n if (chapters.length === 0) {\n setErrorMsg(`Dictionary ${dictId} is empty.`);\n setPhase('error');\n return;\n }\n const idx = Math.max(0, Math.min(chapters.length - 1, chapterIndex));\n const playlist = buildPlaylist(chapters[idx]!, mode);\n setLoaded({ playlist, totalChapters: chapters.length });\n setPhase('typing');\n } catch (err) {\n if (cancelled) return;\n setErrorMsg((err as Error).message);\n setPhase('error');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [dictId, chapterIndex, mode, cfg.chapterSize]);\n\n if (phase === 'loading') {\n return <Centered text=\"loading…\" color={PALETTE.muted} />;\n }\n if (phase === 'error') {\n return <ErrorView msg={errorMsg ?? 'Unknown error'} />;\n }\n if (!loaded) return null;\n\n return (\n <PracticeRunner\n key={`${dictId}-${chapterIndex}-${mode}`}\n params={params}\n loaded={loaded}\n phase={phase}\n setPhase={setPhase}\n />\n );\n}\n\nfunction PracticeRunner({\n params,\n loaded,\n phase,\n setPhase,\n}: {\n params: PracticeParams;\n loaded: Loaded;\n phase: Phase;\n setPhase: (p: Phase) => void;\n}) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const nav = useNav();\n const { exit } = useApp();\n const goBack = () => (nav.stack.length > 1 ? nav.back() : exit());\n const persist = useSessionPersistence({ dictId, chapterIndex, mode });\n\n const audio = useAudio({\n enabled: cfg.sounds.master,\n accent: cfg.accent,\n autoplayPronunciation: cfg.autoplayPronunciation,\n });\n\n const finishedRef = useRef(false);\n const lastEffectRef = useRef<string | null>(null);\n const lastIndexRef = useRef<number>(-1);\n\n const { session, lastEffect, tick } = useWordLoop({\n playlist: loaded.playlist,\n enabled: phase === 'typing',\n onComplete: (s) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n setPhase('summary');\n Promise.resolve(persist(sessionSummary(s))).catch((err) => {\n console.error('Failed to persist session:', err);\n });\n },\n onEscape: () => setPhase(phase === 'paused' ? 'typing' : 'paused'),\n onTab: () => {\n const cur = session.current ? loaded.playlist[session.current.wordIndex] : undefined;\n if (cur) void audio.pronounce(cur.name);\n },\n });\n\n useEffect(() => {\n if (lastEffect === null) return;\n if (lastEffect === lastEffectRef.current) return;\n lastEffectRef.current = lastEffect;\n if (lastEffect === 'wrong' && cfg.sounds.feedback) audio.wrong();\n if (lastEffect === 'progress' && cfg.sounds.keystroke) audio.keystroke();\n if (lastEffect === 'correct') {\n if (cfg.sounds.feedback) audio.correct();\n if (cfg.sounds.keystroke) audio.keystroke();\n }\n }, [lastEffect, audio, cfg.sounds.feedback, cfg.sounds.keystroke]);\n\n useEffect(() => {\n const idx = session.current?.wordIndex ?? -1;\n if (idx === -1) return;\n if (idx === lastIndexRef.current) return;\n lastIndexRef.current = idx;\n const cur = loaded.playlist[idx];\n const next = loaded.playlist[idx + 1];\n if (cur && cfg.autoplayPronunciation) audio.pronounce(cur.name);\n if (next) audio.prefetch(next.name);\n }, [session.current?.wordIndex, audio, cfg.autoplayPronunciation, loaded.playlist]);\n\n void tick;\n\n useInput(\n (input) => {\n if (input === 'r') setPhase('typing');\n if (input === 'q') goBack();\n },\n { isActive: phase === 'paused' },\n );\n\n useInput(\n (input) => {\n if (input === 'q') {\n goBack();\n return;\n }\n if (input === 'n') {\n const nextIdx = chapterIndex + 1;\n if (mode === 'loop') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex, mode } });\n } else if (mode === 'review' || nextIdx >= loaded.totalChapters) {\n goBack();\n } else {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: nextIdx, mode } });\n }\n return;\n }\n if (input === 'm') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: 0, mode: 'review' } });\n return;\n }\n },\n { isActive: phase === 'summary' },\n );\n\n if (phase === 'paused') return <PausedView />;\n if (phase === 'summary') {\n return (\n <SummaryView\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n summary={sessionSummary(session)}\n />\n );\n }\n\n const currentWord = session.current\n ? loaded.playlist[session.current.wordIndex]\n : loaded.playlist[loaded.playlist.length - 1];\n const inputState = session.current?.input ?? { target: '', typed: '', errorsThisWord: 0 };\n const elapsedMs = Date.now() - session.startedAt;\n const completed = session.results.length;\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const minutes = elapsedMs / 60000;\n const wpm = minutes > 0 ? Math.round((completed / minutes) * 10) / 10 : 0;\n\n return (\n <TypingLayout\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n accent={cfg.accent}\n completed={completed}\n total={loaded.playlist.length}\n errors={errors}\n wpm={wpm}\n elapsedMs={elapsedMs}\n target={currentWord?.name ?? ''}\n typed={inputState.typed}\n flashError={lastEffect === 'wrong'}\n hideTarget={mode === 'dictation'}\n phonetic={pickPhonetic(currentWord, cfg.accent)}\n translation={currentWord?.trans ?? []}\n />\n );\n}\n\nfunction pickPhonetic(word: Word | undefined, accent: 'us' | 'uk'): string | null {\n if (!word) return null;\n const p = accent === 'us' ? word.usphone : word.ukphone;\n return p ? `/${p}/` : null;\n}\n\nfunction fmtTime(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction TypingLayout(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n errors: number;\n wpm: number;\n elapsedMs: number;\n target: string;\n typed: string;\n flashError: boolean;\n hideTarget: boolean;\n phonetic: string | null;\n translation: string[];\n}) {\n const progressFrac = props.total === 0 ? 0 : props.completed / props.total;\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <StatusBar\n dictId={props.dictId}\n chapterIndex={props.chapterIndex}\n totalChapters={props.totalChapters}\n mode={props.mode}\n accent={props.accent}\n completed={props.completed}\n total={props.total}\n elapsedMs={props.elapsedMs}\n />\n\n <Box flexGrow={1} flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\">\n <BigWord\n target={props.target}\n typed={props.typed}\n error={props.flashError}\n hideTarget={props.hideTarget}\n />\n\n {props.phonetic && (\n <Box marginTop={1}>\n <Text italic color={PALETTE.muted}>\n {props.phonetic}\n </Text>\n </Box>\n )}\n\n {props.translation.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\" alignItems=\"center\">\n {props.translation.slice(0, 2).map((t, i) => (\n <Text key={i} color={PALETTE.primary}>\n {t}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <ProgressBar frac={progressFrac} />\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n {props.completed}/{props.total} · {fmtTime(props.elapsedMs)} · {props.wpm} wpm · {props.errors} errors\n </Text>\n </Box>\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n Ctrl+N skip · Esc pause · Tab replay · Ctrl+C quit\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nfunction StatusBar(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n elapsedMs: number;\n}) {\n const left =\n props.mode === 'review'\n ? `${props.dictId} · review · ${props.accent}`\n : `${props.dictId} · ch ${props.chapterIndex + 1}/${props.totalChapters} · ${props.mode} · ${props.accent}`;\n const right = `${props.completed}/${props.total} · ${fmtTime(props.elapsedMs)}`;\n return (\n <Box>\n <Text color={PALETTE.muted}>{left}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{right}</Text>\n </Box>\n );\n}\n\nfunction ProgressBar({ frac }: { frac: number }) {\n const cols = process.stdout.columns ?? 80;\n const width = Math.max(20, Math.min(72, cols - 16));\n const filled = Math.round(width * Math.max(0, Math.min(1, frac)));\n const empty = width - filled;\n return (\n <Box justifyContent=\"center\">\n <Text color={PALETTE.accent}>{'━'.repeat(filled)}</Text>\n <Text color={PALETTE.muted}>{'─'.repeat(empty)}</Text>\n </Box>\n );\n}\n\nfunction PausedView() {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <BigText text=\"paused\" font=\"tiny\" colors={[PALETTE.warning]} />\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[r] resume · [q] quit to menu</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ErrorView({ msg }: { msg: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.error}>{msg}</Text>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] back to menu</Text>\n </Box>\n <BackKey />\n </Box>\n );\n}\n\nfunction BackKey() {\n const nav = useNav();\n useInput((input, key) => {\n if (input === 'q' || key.escape) nav.back();\n });\n return null;\n}\n\nfunction Centered({ text, color }: { text: string; color: string }) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={color}>{text}</Text>\n </Box>\n );\n}\n\nfunction SummaryView(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n summary: { wordCount: number; errors: number; durationMs: number; perWordErrors: Record<string, number> };\n}) {\n const { summary } = props;\n const minutes = summary.durationMs / 60000;\n const wpm = minutes > 0 ? Math.round((summary.wordCount / minutes) * 10) / 10 : 0;\n const errorWords = Object.keys(summary.perWordErrors).length;\n const acc = summary.wordCount === 0 ? 1 : Math.max(0, (summary.wordCount - errorWords) / summary.wordCount);\n const accPct = Math.round(acc * 1000) / 10;\n\n const subtitle =\n props.mode === 'review'\n ? `${props.dictId} · review`\n : `${props.dictId} · chapter ${props.chapterIndex + 1}/${props.totalChapters} · ${props.mode}`;\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" paddingY={1} width=\"100%\" height=\"100%\">\n <BigText text=\"complete\" font=\"tiny\" colors={[PALETTE.success]} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{subtitle}</Text>\n </Box>\n\n <Box marginTop={3} flexDirection=\"row\" justifyContent=\"center\">\n <StatCard label=\"words\" value={String(summary.wordCount)} color={PALETTE.text} />\n <StatCard\n label=\"errors\"\n value={String(summary.errors)}\n color={summary.errors > 0 ? PALETTE.error : PALETTE.muted}\n />\n <StatCard label=\"wpm\" value={String(wpm)} color={PALETTE.accent} />\n <StatCard label=\"accuracy\" value={`${accPct}%`} color={PALETTE.accent} />\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>elapsed {fmtTime(summary.durationMs)}</Text>\n </Box>\n\n <Box flexGrow={1} />\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n [n] next chapter · [m] review mistakes · [q] back to menu\n </Text>\n </Box>\n </Box>\n );\n}\n\nfunction StatCard({ label, value, color }: { label: string; value: string; color: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" marginX={2}>\n <BigText text={value} font=\"tiny\" colors={[color]} />\n <Text color={PALETTE.muted}>{label}</Text>\n </Box>\n );\n}\n","export function shuffle<T>(arr: readonly T[], rng: () => number = Math.random): T[] {\n const out = [...arr];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1));\n const tmp = out[i]!;\n out[i] = out[j]!;\n out[j] = tmp;\n }\n return out;\n}\n\nexport function mulberry32(seed: number): () => number {\n let t = seed >>> 0;\n return () => {\n t = (t + 0x6d2b79f5) >>> 0;\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\n r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import type { Word } from './dictionary.js';\nimport { shuffle, mulberry32 } from '../util/shuffle.js';\n\nexport type Mode = 'order' | 'dictation' | 'review' | 'random' | 'loop';\n\nexport function chunkChapters(words: Word[], chapterSize: number): Word[][] {\n if (chapterSize <= 0) throw new Error('chapterSize must be positive');\n const chunks: Word[][] = [];\n for (let i = 0; i < words.length; i += chapterSize) {\n chunks.push(words.slice(i, i + chapterSize));\n }\n return chunks;\n}\n\nexport function chapterCount(totalWords: number, chapterSize: number): number {\n return Math.ceil(totalWords / chapterSize);\n}\n\n/**\n * Build a play list for a chapter, applying the given mode.\n * - order: return as-is\n * - dictation: same as order (hide-the-word behavior is UI-only)\n * - random: single shuffled pass\n * - loop: return as-is; the practice screen drives the repeat\n * - review: caller passes the mistake-book words, we just chunk those\n */\nexport function buildPlaylist(chapter: Word[], mode: Mode, seed?: number): Word[] {\n if (mode === 'random') {\n const rng = seed === undefined ? Math.random : mulberry32(seed);\n return shuffle(chapter, rng);\n }\n return chapter;\n}\n","export type InputState = {\n target: string;\n typed: string;\n errorsThisWord: number;\n};\n\nexport type InputEvent =\n | { type: 'char'; ch: string }\n | { type: 'backspace' }\n | { type: 'reset' };\n\nexport type InputEffect = 'none' | 'progress' | 'wrong' | 'correct' | 'skipped';\n\nexport function initialState(target: string): InputState {\n return { target, typed: '', errorsThisWord: 0 };\n}\n\nexport function reduce(state: InputState, ev: InputEvent): { state: InputState; effect: InputEffect } {\n switch (ev.type) {\n case 'reset':\n return { state: { ...state, typed: '' }, effect: 'none' };\n case 'backspace': {\n if (state.typed.length === 0) return { state, effect: 'none' };\n return { state: { ...state, typed: state.typed.slice(0, -1) }, effect: 'none' };\n }\n case 'char': {\n const candidate = state.typed + ev.ch;\n // Compare by code-point index, not byte length, to handle unicode safely.\n const targetUpToCandidate = [...state.target].slice(0, [...candidate].length).join('');\n if (candidate === targetUpToCandidate) {\n if (candidate.length === state.target.length) {\n return { state: { ...state, typed: candidate }, effect: 'correct' };\n }\n return { state: { ...state, typed: candidate }, effect: 'progress' };\n }\n return {\n state: { ...state, typed: '', errorsThisWord: state.errorsThisWord + 1 },\n effect: 'wrong',\n };\n }\n }\n}\n","import type { Word } from './dictionary.js';\nimport { initialState, reduce, type InputEvent, type InputState, type InputEffect } from './input-buffer.js';\n\nexport type SessionWordResult = { word: string; errors: number; durationMs: number; skipped?: boolean };\n\nexport type Session = {\n startedAt: number;\n results: SessionWordResult[];\n current: { wordIndex: number; wordStartedAt: number; input: InputState } | null;\n finishedAt: number | null;\n playlist: Word[];\n};\n\nexport function startSession(playlist: Word[], now = Date.now()): Session {\n if (playlist.length === 0) {\n return { startedAt: now, results: [], current: null, finishedAt: now, playlist };\n }\n return {\n startedAt: now,\n results: [],\n current: { wordIndex: 0, wordStartedAt: now, input: initialState(playlist[0]!.name) },\n finishedAt: null,\n playlist,\n };\n}\n\nexport function feedSession(session: Session, ev: InputEvent, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const { state, effect } = reduce(session.current.input, ev);\n if (effect === 'correct') {\n const finished: SessionWordResult = {\n word: state.target,\n errors: state.errorsThisWord,\n durationMs: now - session.current.wordStartedAt,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, finished];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect,\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect,\n };\n }\n return {\n session: {\n ...session,\n current: { ...session.current, input: state },\n },\n effect,\n };\n}\n\nexport function skipSession(session: Session, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const result: SessionWordResult = {\n word: session.current.input.target,\n errors: 0,\n durationMs: now - session.current.wordStartedAt,\n skipped: true,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, result];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect: 'skipped',\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect: 'skipped',\n };\n}\n\nexport function sessionSummary(session: Session): {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n} {\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const durationMs =\n (session.finishedAt ?? Date.now()) - session.startedAt;\n const perWordErrors: Record<string, number> = {};\n for (const r of session.results) {\n if (r.errors > 0) perWordErrors[r.word] = (perWordErrors[r.word] ?? 0) + r.errors;\n }\n return { wordCount: session.results.length, errors, durationMs, perWordErrors };\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { readJson, writeJsonAtomic } from '../infra/fs-store.js';\n\nexport const MistakeBookSchema = z.record(\n z.string(),\n z.object({\n count: z.number().int().nonnegative(),\n lastSeen: z.string(),\n dictIds: z.array(z.string()).default([]),\n }),\n);\n\nexport type MistakeBook = z.infer<typeof MistakeBookSchema>;\n\nexport async function loadMistakes(): Promise<MistakeBook> {\n const raw = await readJson<unknown>(paths.mistakes);\n if (!raw) return {};\n const parsed = MistakeBookSchema.safeParse(raw);\n if (!parsed.success) {\n console.warn('Mistake book is corrupt; starting fresh');\n return {};\n }\n return parsed.data;\n}\n\nexport async function saveMistakes(book: MistakeBook): Promise<void> {\n await writeJsonAtomic(paths.mistakes, book);\n}\n\nexport function bump(book: MistakeBook, word: string, dictId: string, delta = 1): MistakeBook {\n const prev = book[word] ?? { count: 0, lastSeen: new Date(0).toISOString(), dictIds: [] };\n const dictIds = prev.dictIds.includes(dictId) ? prev.dictIds : [...prev.dictIds, dictId];\n return {\n ...book,\n [word]: {\n count: prev.count + delta,\n lastSeen: new Date().toISOString(),\n dictIds,\n },\n };\n}\n\nexport function topN(book: MistakeBook, n: number): Array<[string, MistakeBook[string]]> {\n return Object.entries(book)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, n);\n}\n","import { useEffect, useReducer, useRef, useState } from 'react';\nimport { useInput, useApp } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport { startSession, feedSession, skipSession, type Session } from '../../domain/session.js';\nimport type { InputEffect } from '../../domain/input-buffer.js';\n\ntype Action =\n | { type: 'event'; input: string; key: { backspace?: boolean; delete?: boolean; tab?: boolean; escape?: boolean; return?: boolean; ctrl?: boolean }; now: number }\n | { type: 'start'; playlist: Word[]; now: number }\n | { type: 'skip'; now: number };\n\nfunction reducer(state: { session: Session; lastEffect: InputEffect | null }, action: Action) {\n if (action.type === 'start') {\n return { session: startSession(action.playlist, action.now), lastEffect: null };\n }\n if (action.type === 'skip') {\n const r = skipSession(state.session, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.type === 'event') {\n if (action.key.backspace || action.key.delete) {\n const r = feedSession(state.session, { type: 'backspace' }, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.input.length === 0) return state;\n let session = state.session;\n let lastEffect: InputEffect | null = state.lastEffect;\n for (const c of action.input) {\n const r = feedSession(session, { type: 'char', ch: c }, action.now);\n session = r.session;\n lastEffect = r.effect;\n if (session.finishedAt !== null) break;\n }\n return { session, lastEffect };\n }\n return state;\n}\n\nexport type UseWordLoopOpts = {\n playlist: Word[];\n onComplete: (session: Session) => void;\n onTab?: () => void;\n onEscape?: () => void;\n onSkip?: () => void;\n enabled?: boolean;\n};\n\nexport function useWordLoop({ playlist, onComplete, onTab, onEscape, onSkip, enabled = true }: UseWordLoopOpts) {\n const [state, dispatch] = useReducer(reducer, undefined, () => ({\n session: startSession(playlist, Date.now()),\n lastEffect: null as InputEffect | null,\n }));\n const completedRef = useRef(false);\n const [tick, setTick] = useState(0);\n const { exit } = useApp();\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') {\n exit();\n return;\n }\n if (key.ctrl && input === 'n') {\n onSkip?.();\n dispatch({ type: 'skip', now: Date.now() });\n return;\n }\n if (key.escape) {\n onEscape?.();\n return;\n }\n if (key.tab) {\n onTab?.();\n return;\n }\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.return) return;\n if (key.ctrl || key.meta) return;\n const cleaned = [...input].filter((c) => {\n const code = c.codePointAt(0)!;\n return code === 0x20 || (code >= 0x21 && code !== 0x7f);\n }).join('');\n if (cleaned.length === 0) return;\n dispatch({ type: 'event', input: cleaned, key, now: Date.now() });\n },\n { isActive: enabled },\n );\n\n useEffect(() => {\n if (state.session.finishedAt !== null && !completedRef.current) {\n completedRef.current = true;\n onComplete(state.session);\n }\n }, [state.session, onComplete]);\n\n useEffect(() => {\n if (state.session.finishedAt !== null) return;\n const id = setInterval(() => setTick((t) => t + 1), 1000);\n return () => clearInterval(id);\n }, [state.session.finishedAt]);\n\n return { session: state.session, lastEffect: state.lastEffect, tick };\n}\n","import { useEffect, useRef } from 'react';\nimport {\n initAudio,\n playCorrect,\n playWrong,\n playKeystroke,\n playPronunciation,\n prefetchPronunciation,\n} from '../../infra/audio.js';\n\ntype Opts = {\n enabled: boolean;\n accent: 'us' | 'uk';\n autoplayPronunciation: boolean;\n};\n\nexport type AudioControls = {\n keystroke: () => void;\n correct: () => void;\n wrong: () => void;\n pronounce: (word: string) => void;\n prefetch: (word: string) => void;\n};\n\nexport function useAudio(opts: Opts): AudioControls {\n const initedRef = useRef(false);\n useEffect(() => {\n if (initedRef.current) return;\n initedRef.current = true;\n initAudio(!opts.enabled).catch(() => undefined);\n }, [opts.enabled]);\n\n return {\n keystroke: () => opts.enabled && playKeystroke(),\n correct: () => opts.enabled && playCorrect(),\n wrong: () => opts.enabled && playWrong(),\n pronounce: (word) => {\n if (!opts.enabled) return;\n if (opts.autoplayPronunciation) void playPronunciation(word, opts.accent);\n },\n prefetch: (word) => {\n if (!opts.enabled) return;\n void prefetchPronunciation(word, opts.accent);\n },\n };\n}\n","import { useCallback } from 'react';\nimport { appendSession, type SessionRecord } from '../../domain/stats.js';\nimport { loadMistakes, saveMistakes, bump } from '../../domain/mistakes.js';\nimport type { Mode } from '../../domain/chapters.js';\n\ntype Summary = {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\nexport function useSessionPersistence(meta: { dictId: string; chapterIndex: number; mode: Mode }) {\n return useCallback(\n async (summary: Summary): Promise<void> => {\n const rec: SessionRecord = {\n ts: new Date().toISOString(),\n dictId: meta.dictId,\n chapter: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n };\n await appendSession(rec);\n const dirty = Object.entries(summary.perWordErrors).filter(([, n]) => n > 0);\n if (dirty.length === 0) return;\n let book = await loadMistakes();\n for (const [word, n] of dirty) book = bump(book, word, meta.dictId, n);\n await saveMistakes(book);\n },\n [meta.dictId, meta.chapterIndex, meta.mode],\n );\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { appendJsonl, readJsonl } from '../infra/fs-store.js';\n\nexport const SessionRecordSchema = z.object({\n ts: z.string(),\n dictId: z.string(),\n chapter: z.number().int().nonnegative(),\n mode: z.string(),\n wordCount: z.number().int().nonnegative(),\n errors: z.number().int().nonnegative(),\n durationMs: z.number().int().nonnegative(),\n perWordErrors: z.record(z.string(), z.number().int().nonnegative()).default({}),\n});\n\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\nexport async function appendSession(record: SessionRecord): Promise<void> {\n await appendJsonl(paths.stats, record);\n}\n\nexport async function loadSessions(): Promise<SessionRecord[]> {\n const rows = await readJsonl<unknown>(paths.stats);\n return rows\n .map((r) => SessionRecordSchema.safeParse(r))\n .filter((r): r is { success: true; data: SessionRecord } => r.success)\n .map((r) => r.data);\n}\n\nexport function computeWPM(record: SessionRecord): number {\n if (record.durationMs === 0) return 0;\n const minutes = record.durationMs / 60000;\n return Math.round((record.wordCount / minutes) * 10) / 10;\n}\n\nexport function accuracy(record: SessionRecord): number {\n // Word-level: fraction of words finished without any mistake (first-try rate).\n if (record.wordCount === 0) return 1;\n const wordsWithErrors = Object.keys(record.perWordErrors).length;\n return Math.max(0, Math.min(1, (record.wordCount - wordsWithErrors) / record.wordCount));\n}\n\nexport function dailyStreak(sessions: SessionRecord[], now = new Date()): number {\n if (sessions.length === 0) return 0;\n const days = new Set<string>();\n for (const s of sessions) days.add(s.ts.slice(0, 10));\n let streak = 0;\n const cur = new Date(now);\n while (true) {\n const key = cur.toISOString().slice(0, 10);\n if (!days.has(key)) break;\n streak++;\n cur.setUTCDate(cur.getUTCDate() - 1);\n }\n return streak;\n}\n\nconst SPARK = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];\n\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return '';\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = Math.max(1, max - min);\n return values\n .map((v) => {\n const idx = Math.floor(((v - min) / range) * (SPARK.length - 1));\n return SPARK[Math.max(0, Math.min(SPARK.length - 1, idx))]!;\n })\n .join('');\n}\n\nexport type DailyBucket = { date: string; wpm: number; accuracy: number; sessions: number };\n\nexport function dailyBuckets(sessions: SessionRecord[], days: number, now = new Date()): DailyBucket[] {\n const out: DailyBucket[] = [];\n const byDay = new Map<string, SessionRecord[]>();\n for (const s of sessions) {\n const key = s.ts.slice(0, 10);\n const arr = byDay.get(key) ?? [];\n arr.push(s);\n byDay.set(key, arr);\n }\n const cur = new Date(now);\n cur.setUTCDate(cur.getUTCDate() - (days - 1));\n for (let i = 0; i < days; i++) {\n const key = cur.toISOString().slice(0, 10);\n const todays = byDay.get(key) ?? [];\n if (todays.length === 0) {\n out.push({ date: key, wpm: 0, accuracy: 0, sessions: 0 });\n } else {\n const wpm = todays.reduce((a, s) => a + computeWPM(s), 0) / todays.length;\n const acc = todays.reduce((a, s) => a + accuracy(s), 0) / todays.length;\n out.push({ date: key, wpm, accuracy: acc, sessions: todays.length });\n }\n cur.setUTCDate(cur.getUTCDate() + 1);\n }\n return out;\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav, type DictParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { loadRegistry } from '../../infra/registry-store.js';\nimport {\n isLocallyAvailable,\n pullDictionary,\n removeDictionary,\n} from '../../infra/dict-downloader.js';\nimport type { DictionaryEntry } from '../../domain/dictionary.js';\nimport { filterRegistry } from '../../domain/dictionary.js';\n\ntype Row = { entry: DictionaryEntry; local: boolean };\ntype PendingAction =\n | { kind: 'pulling'; id: string }\n | { kind: 'removing'; id: string }\n | { kind: 'error'; id: string; msg: string }\n | null;\n\nexport function DictBrowser({ params }: { params?: DictParams }) {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n const [filter, setFilter] = useState('');\n const [filterFocus, setFilterFocus] = useState(false);\n const [pending, setPending] = useState<PendingAction>(null);\n const [tick, setTick] = useState(0);\n\n const refresh = async () => {\n const reg = await loadRegistry();\n const flagged = await Promise.all(\n reg.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n setRows(flagged);\n setLoading(false);\n };\n\n useEffect(() => {\n void refresh();\n }, [tick]);\n\n const filtered = filter\n ? rows.filter((r) => filterRegistry([r.entry], filter).length > 0)\n : rows;\n const safeSelected = Math.max(0, Math.min(filtered.length - 1, selected));\n const current = filtered[safeSelected];\n\n useInput((input, key) => {\n if (filterFocus) {\n if (key.escape || key.return) {\n setFilterFocus(false);\n return;\n }\n if (key.backspace || key.delete) {\n setFilter((f) => f.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setFilter((f) => f + input);\n }\n return;\n }\n if (key.upArrow) setSelected((i) => Math.max(0, i - 1));\n if (key.downArrow) setSelected((i) => Math.min(filtered.length - 1, i + 1));\n if (input === '/') {\n setFilterFocus(true);\n return;\n }\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (!current) return;\n if (key.return) {\n void (async () => {\n await setCfg({ ...cfg, defaultDict: current.entry.id });\n if (params?.pickerMode === 'choose-then-practice') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.back();\n }\n })();\n return;\n }\n if (input === 'p') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n return;\n }\n if (input === 'r' && current.local) {\n setPending({ kind: 'removing', id: current.entry.id });\n void (async () => {\n try {\n await removeDictionary(current.entry.id);\n setPending(null);\n setTick((t) => t + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n return;\n }\n if (input === 'u') {\n setPending({ kind: 'pulling', id: current.entry.id });\n void (async () => {\n try {\n await pullDictionary(current.entry.id);\n setPending(null);\n setTick((t) => t + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>loading dictionaries…</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n Dictionaries\n </Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>\n {filterFocus ? `/ ${filter}_` : filter ? `/ ${filter}` : `${filtered.length} entries`}\n </Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"60%\">\n {filtered.slice(Math.max(0, safeSelected - 8), safeSelected + 16).map((row, vi) => {\n const i = Math.max(0, safeSelected - 8) + vi;\n const active = i === safeSelected;\n const isDefault = cfg.defaultDict === row.entry.id;\n return (\n <Box key={row.entry.id}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={row.local ? PALETTE.accent : PALETTE.muted}>\n {row.local ? '●' : '○'}\n </Text>\n <Text>{' '}</Text>\n <Text color={isDefault ? PALETTE.success : PALETTE.muted}>\n {isDefault ? '★' : ' '}\n </Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {row.entry.id.slice(0, 14).padEnd(15)}\n </Text>\n <Text color={PALETTE.muted}>\n {String(row.entry.length).padStart(5)}\n </Text>\n </Box>\n );\n })}\n </Box>\n\n <Box flexDirection=\"column\" width=\"40%\" paddingLeft={2}>\n {current && (\n <>\n <Text bold color={PALETTE.text}>\n {current.entry.name}\n </Text>\n <Text color={PALETTE.muted}>{current.entry.id}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>\n {current.entry.language} · {current.entry.category} · {current.entry.length} words\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.primary}>{current.entry.description || '(no description)'}</Text>\n </Box>\n {current.entry.tags.length > 0 && (\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>tags: {current.entry.tags.join(', ')}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text color={current.local ? PALETTE.accent : PALETTE.muted}>\n {current.local ? 'local ✓' : 'not local'}\n </Text>\n {cfg.defaultDict === current.entry.id && (\n <Text color={PALETTE.success}> · default ★</Text>\n )}\n </Box>\n </>\n )}\n </Box>\n </Box>\n\n {pending && (\n <Box marginTop={1}>\n {pending.kind === 'pulling' && (\n <Text color={PALETTE.warning}>pulling {pending.id}…</Text>\n )}\n {pending.kind === 'removing' && (\n <Text color={PALETTE.warning}>removing {pending.id}…</Text>\n )}\n {pending.kind === 'error' && (\n <Text color={PALETTE.error}>error on {pending.id}: {pending.msg}</Text>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>\n ↑/↓ select · Enter set default · p practice · u pull · r remove · / filter · Esc back\n </Text>\n </Box>\n </Box>\n );\n}\n","import { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { setByPath, type Config } from '../../infra/config-store.js';\nimport { PALETTE } from '../components/BigWord.js';\n\ntype FieldSpec =\n | { kind: 'enum'; path: string; label: string; options: string[] }\n | { kind: 'bool'; path: string; label: string }\n | { kind: 'int'; path: string; label: string; min: number; max: number }\n | { kind: 'string'; path: string; label: string }\n | { kind: 'dictRef'; path: 'defaultDict'; label: string };\n\nconst FIELDS: FieldSpec[] = [\n { kind: 'dictRef', path: 'defaultDict', label: 'default dict' },\n { kind: 'enum', path: 'defaultMode', label: 'default mode', options: ['order', 'dictation', 'review', 'random', 'loop'] },\n { kind: 'enum', path: 'accent', label: 'accent', options: ['us', 'uk'] },\n { kind: 'enum', path: 'mirror', label: 'mirror', options: ['jsdelivr', 'github'] },\n { kind: 'int', path: 'chapterSize', label: 'chapter size', min: 1, max: 200 },\n { kind: 'bool', path: 'autoplayPronunciation', label: 'autoplay pronunciation' },\n { kind: 'bool', path: 'sounds.master', label: 'sounds master' },\n { kind: 'bool', path: 'sounds.keystroke', label: 'sounds keystroke' },\n { kind: 'bool', path: 'sounds.feedback', label: 'sounds feedback' },\n { kind: 'string', path: 'sounds.keySoundName', label: 'sounds key sound' },\n];\n\nfunction getByPath(cfg: Config, path: string): unknown {\n return path.split('.').reduce<unknown>((acc, k) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[k];\n return undefined;\n }, cfg);\n}\n\nexport function ConfigEditor() {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const [selected, setSelected] = useState(0);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const field = FIELDS[selected]!;\n const currentValue = getByPath(cfg, field.path);\n\n const commit = async (raw: string) => {\n try {\n const next = setByPath(cfg, field.path, raw);\n await setCfg(next);\n setEditing(false);\n setError(null);\n } catch (err) {\n setError((err as Error).message);\n }\n };\n\n useInput((input, key) => {\n if (editing && field.kind === 'string') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) setDraft((d) => d + input);\n return;\n }\n if (editing && field.kind === 'int') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (/^[0-9]$/.test(input)) setDraft((d) => d + input);\n return;\n }\n\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => (i - 1 + FIELDS.length) % FIELDS.length);\n setError(null);\n return;\n }\n if (key.downArrow) {\n setSelected((i) => (i + 1) % FIELDS.length);\n setError(null);\n return;\n }\n if (field.kind === 'bool' && (input === ' ' || key.return)) {\n void commit(currentValue ? 'false' : 'true');\n return;\n }\n if (field.kind === 'enum' && (key.leftArrow || key.rightArrow)) {\n const idx = field.options.indexOf(String(currentValue));\n const delta = key.rightArrow ? 1 : -1;\n const next = field.options[(idx + delta + field.options.length) % field.options.length]!;\n void commit(next);\n return;\n }\n if (field.kind === 'dictRef' && key.return) {\n nav.navigate({ name: 'dict', params: { pickerMode: 'set-default' } });\n return;\n }\n if ((field.kind === 'string' || field.kind === 'int') && key.return) {\n setDraft(String(currentValue ?? ''));\n setEditing(true);\n setError(null);\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n Config\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {FIELDS.map((f, i) => {\n const active = i === selected;\n const value = getByPath(cfg, f.path);\n const display = renderValue(f, value, active && editing ? draft : null);\n return (\n <Box key={f.path}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {f.label.padEnd(28)}\n </Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{display}</Text>\n </Box>\n );\n })}\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>! {error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{hintFor(field, editing)}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction renderValue(field: FieldSpec, value: unknown, draft: string | null): string {\n if (draft !== null) return `${draft}_`;\n if (field.kind === 'bool') return value ? '✓ on' : '✗ off';\n if (field.kind === 'dictRef') return String(value ?? '(none)');\n if (field.kind === 'enum') return `< ${value} >`;\n return String(value ?? '');\n}\n\nfunction hintFor(field: FieldSpec, editing: boolean): string {\n if (editing) return 'type to edit · Enter save · Esc cancel';\n if (field.kind === 'bool') return 'space toggle · ↑/↓ move · Esc back';\n if (field.kind === 'enum') return '←/→ cycle · ↑/↓ move · Esc back';\n if (field.kind === 'dictRef') return 'Enter pick dict · ↑/↓ move · Esc back';\n return 'Enter edit · ↑/↓ move · Esc back';\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport {\n loadSessions,\n computeWPM,\n accuracy,\n dailyBuckets,\n sparkline,\n dailyStreak,\n type SessionRecord,\n} from '../../domain/stats.js';\nimport { loadMistakes, topN, type MistakeBook } from '../../domain/mistakes.js';\n\nconst DAY_WINDOWS = [7, 14, 30, 90];\n\nexport function StatsViewer() {\n const nav = useNav();\n const [sessions, setSessions] = useState<SessionRecord[] | null>(null);\n const [book, setBook] = useState<MistakeBook | null>(null);\n const [windowIdx, setWindowIdx] = useState(1);\n\n useEffect(() => {\n void (async () => {\n const [s, b] = await Promise.all([loadSessions(), loadMistakes()]);\n setSessions(s);\n setBook(b);\n })();\n }, []);\n\n useInput((input, key) => {\n if (key.escape || input === 'b' || input === 'q') {\n nav.back();\n return;\n }\n if (input === 'n') setWindowIdx((i) => (i + 1) % DAY_WINDOWS.length);\n if (input === 'N') setWindowIdx((i) => (i - 1 + DAY_WINDOWS.length) % DAY_WINDOWS.length);\n });\n\n if (!sessions || !book) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>loading stats…</Text>\n </Box>\n );\n }\n\n if (sessions.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>No practice history yet.</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>Run a practice session first.</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] back</Text>\n </Box>\n </Box>\n );\n }\n\n const days = DAY_WINDOWS[windowIdx]!;\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n const recent = sessions.slice(-5).reverse();\n const top = topN(book, 8);\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n Stats\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={PALETTE.muted}>lifetime</Text>\n <Box marginTop={1}>\n <Stat label=\"sessions\" value={String(sessions.length)} />\n <Stat label=\"words\" value={String(totalWords)} />\n <Stat label=\"errors\" value={String(totalErrors)} />\n <Stat label=\"wpm\" value={String(overallWpm)} accent />\n <Stat label=\"accuracy\" value={`${Math.round(overallAcc * 1000) / 10}%`} accent />\n <Stat label=\"streak\" value={`${streak}d`} accent />\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>last {days} days (n / N to cycle window)</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text color={PALETTE.muted}>{'wpm '.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.wpm))}</Text>\n <Text color={PALETTE.muted}> max {Math.round(Math.max(...buckets.map((b) => b.wpm)))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{'accuracy'.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.accuracy * 100))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{'sessions'.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.sessions))}</Text>\n </Box>\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>recent sessions</Text>\n {recent.map((s, i) => (\n <Box key={i}>\n <Text color={PALETTE.muted}> {s.ts.replace('T', ' ').slice(0, 16)} </Text>\n <Text color={PALETTE.text}>{s.dictId.padEnd(14)}</Text>\n <Text color={PALETTE.muted}>\n {' '}ch{String(s.chapter + 1).padStart(3)} {s.mode.padEnd(9)} {String(s.wordCount).padStart(3)}w {s.errors}err {computeWPM(s)}wpm {Math.round(accuracy(s) * 1000) / 10}%\n </Text>\n </Box>\n ))}\n </Box>\n\n {top.length > 0 && (\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>top mistakes</Text>\n {top.map(([word, entry]) => (\n <Box key={word}>\n <Text color={PALETTE.error}> {String(entry.count).padStart(3)} </Text>\n <Text color={PALETTE.text}>{word.padEnd(20)}</Text>\n <Text color={PALETTE.muted}>{entry.dictIds.join(', ')}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n <Box flexGrow={1} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>n / N cycle window · q back</Text>\n </Box>\n </Box>\n );\n}\n\nfunction Stat({ label, value, accent = false }: { label: string; value: string; accent?: boolean }) {\n return (\n <Box marginRight={3}>\n <Text color={PALETTE.muted}>{label} </Text>\n <Text bold color={accent ? PALETTE.accent : PALETTE.text}>\n {value}\n </Text>\n </Box>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../../infra/paths.js';\nimport { loadLocalDictionary } from '../../infra/dict-downloader.js';\nimport { loadMistakes, type MistakeBook } from '../../domain/mistakes.js';\nimport type { Word } from '../../domain/dictionary.js';\n\ntype Hit = { dictId: string; word: Word };\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function WordLookup() {\n const nav = useNav();\n const [query, setQuery] = useState('');\n const [allWords, setAllWords] = useState<Hit[]>([]);\n const [book, setBook] = useState<MistakeBook>({});\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n\n useEffect(() => {\n void (async () => {\n const ids = await listLocalDictIds();\n const collected: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) collected.push({ dictId: id, word: w });\n }\n setAllWords(collected);\n setBook(await loadMistakes());\n setLoading(false);\n })();\n }, []);\n\n const q = query.toLowerCase().trim();\n const filtered = q\n ? allWords.filter((h) => h.word.name.toLowerCase().includes(q)).slice(0, 50)\n : [];\n\n useInput((input, key) => {\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setSelected((i) => Math.min(filtered.length - 1, i + 1));\n return;\n }\n if (key.backspace || key.delete) {\n setQuery((s) => s.slice(0, -1));\n setSelected(0);\n return;\n }\n if (input && !key.ctrl && !key.meta && input.trim().length > 0) {\n setQuery((s) => s + input);\n setSelected(0);\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>indexing local dictionaries…</Text>\n </Box>\n );\n }\n\n if (allWords.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>No local dictionaries.</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>Pull one in Dictionaries first.</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[Esc] back</Text>\n </Box>\n </Box>\n );\n }\n\n const current = filtered[selected];\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>Word lookup</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{allWords.length} words across local dicts</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{'> '}</Text>\n <Text color={PALETTE.text}>{query}</Text>\n <Text color={PALETTE.accent}>_</Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"40%\">\n {filtered.map((h, i) => {\n const active = i === selected;\n return (\n <Box key={`${h.dictId}-${h.word.name}-${i}`}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {h.word.name.padEnd(20)}\n </Text>\n <Text color={PALETTE.muted}>{h.dictId}</Text>\n </Box>\n );\n })}\n {filtered.length === 0 && q && (\n <Text color={PALETTE.muted}>no matches for \"{query}\"</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" width=\"60%\" paddingLeft={2}>\n {current && (\n <>\n <Text bold color={PALETTE.text}>{current.word.name}</Text>\n <Box marginTop={1}>\n {current.word.usphone && (\n <Text color={PALETTE.muted}>US /{current.word.usphone}/ </Text>\n )}\n {current.word.ukphone && (\n <Text color={PALETTE.muted}>UK /{current.word.ukphone}/</Text>\n )}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {(current.word.trans ?? []).map((t, i) => (\n <Text key={i} color={PALETTE.primary}>· {t}</Text>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>in: {current.dictId}</Text>\n </Box>\n {book[current.word.name] && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>\n mistakes: {book[current.word.name]!.count}\n </Text>\n <Text color={PALETTE.muted}>\n {' '}(last {book[current.word.name]!.lastSeen.slice(0, 10)})\n </Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>type to filter · ↑/↓ select · Esc back</Text>\n </Box>\n </Box>\n );\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadSessions, computeWPM, accuracy, dailyBuckets, sparkline, dailyStreak } from '../domain/stats.js';\nimport { loadMistakes, topN } from '../domain/mistakes.js';\n\nexport function buildStatsCommand(): Command {\n return new Command('stats')\n .description('Show practice history and trends')\n .option('-d, --days <n>', 'window size for trend (default 14)', '14')\n .option('--top <n>', 'how many top mistakes to show (default 10)', '10')\n .action(async (opts: { days: string; top: string }) => {\n const days = Math.max(1, Number(opts.days) || 14);\n const topCount = Math.max(1, Number(opts.top) || 10);\n const sessions = await loadSessions();\n const book = await loadMistakes();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No practice history yet. Run `qwerty practice <dict>` to get started.'));\n return;\n }\n\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n console.log(chalk.bold('\\nLifetime'));\n console.log(` ${chalk.dim('sessions')} ${sessions.length} ${chalk.dim('words')} ${totalWords} ${chalk.dim('errors')} ${totalErrors}`);\n console.log(` ${chalk.dim('avg wpm')} ${overallWpm} ${chalk.dim('avg accuracy')} ${Math.round(overallAcc * 1000) / 10}% ${chalk.dim('streak')} ${chalk.bold(streak)}d`);\n\n console.log(chalk.bold(`\\nLast ${days} days`));\n console.log(` ${chalk.dim('wpm ')} ${sparkline(buckets.map((b) => b.wpm))} ${chalk.dim('max')} ${Math.round(Math.max(...buckets.map((b) => b.wpm)))}`);\n console.log(` ${chalk.dim('accuracy')} ${sparkline(buckets.map((b) => b.accuracy * 100))} ${chalk.dim('range')} ${Math.round(Math.min(...buckets.map((b) => b.accuracy * 100)))}-${Math.round(Math.max(...buckets.map((b) => b.accuracy * 100)))}%`);\n console.log(` ${chalk.dim('sessions')} ${sparkline(buckets.map((b) => b.sessions))}`);\n\n const recent = sessions.slice(-5).reverse();\n console.log(chalk.bold('\\nLast 5 sessions'));\n for (const s of recent) {\n const wpm = computeWPM(s);\n const acc = Math.round(accuracy(s) * 1000) / 10;\n console.log(\n ` ${chalk.dim(s.ts.replace('T', ' ').slice(0, 16))} ${chalk.cyan(s.dictId.padEnd(14))} ch${String(s.chapter + 1).padStart(3)} ${s.mode.padEnd(9)} ${String(s.wordCount).padStart(3)}w ${s.errors}err ${wpm}wpm ${acc}%`,\n );\n }\n\n const top = topN(book, topCount);\n if (top.length > 0) {\n console.log(chalk.bold(`\\nTop ${top.length} mistakes`));\n for (const [word, entry] of top) {\n console.log(` ${chalk.red(String(entry.count).padStart(3))} ${chalk.bold(word.padEnd(20))} ${chalk.dim(entry.dictIds.join(', '))}`);\n }\n } else {\n console.log(chalk.bold('\\nTop mistakes'));\n console.log(chalk.dim(' none — keep going'));\n }\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../infra/paths.js';\nimport { loadLocalDictionary } from '../infra/dict-downloader.js';\nimport { loadMistakes } from '../domain/mistakes.js';\nimport { findEntry } from '../infra/registry-store.js';\nimport type { Word } from '../domain/dictionary.js';\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function buildWordCommand(): Command {\n return new Command('word')\n .argument('<keyword>')\n .description('Look up a word across local dictionaries')\n .option('--exact', 'require exact (case-insensitive) match')\n .action(async (keyword: string, opts: { exact?: boolean }) => {\n const q = keyword.toLowerCase();\n const ids = await listLocalDictIds();\n if (ids.length === 0) {\n console.log(chalk.yellow('No local dictionaries. Run `qwerty dict pull <id>` first.'));\n return;\n }\n\n type Hit = { dictId: string; word: Word };\n const hits: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) {\n const wl = w.name.toLowerCase();\n const match = opts.exact ? wl === q : wl.includes(q);\n if (match) hits.push({ dictId: id, word: w });\n }\n }\n\n if (hits.length === 0) {\n console.log(chalk.yellow(`No matches for \"${keyword}\" in ${ids.length} local dictionaries`));\n return;\n }\n\n // Group hits by word name; one block per distinct word.\n const byName = new Map<string, Hit[]>();\n for (const h of hits) {\n const arr = byName.get(h.word.name) ?? [];\n arr.push(h);\n byName.set(h.word.name, arr);\n }\n\n const book = await loadMistakes();\n for (const [name, group] of byName) {\n const first = group[0]!.word;\n console.log();\n console.log(chalk.bold.white(name));\n const us = first.usphone ? `US /${first.usphone}/` : '';\n const uk = first.ukphone ? `UK /${first.ukphone}/` : '';\n if (us || uk) console.log(chalk.dim(` ${[us, uk].filter(Boolean).join(' ')}`));\n for (const t of first.trans ?? []) console.log(chalk.cyan(` · ${t}`));\n const sources = await Promise.all(\n group.map(async (h) => {\n const reg = await findEntry(h.dictId);\n return reg?.name ?? h.dictId;\n }),\n );\n console.log(chalk.dim(` in: ${sources.join(', ')}`));\n const mistake = book[name];\n if (mistake) {\n console.log(chalk.dim(` mistakes: ${mistake.count} (last ${mistake.lastSeen.slice(0, 10)})`));\n }\n }\n console.log();\n });\n}\n","import { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\n\nexport async function runMainMenu(): Promise<void> {\n if (!process.stdout.isTTY) {\n console.log('qwerty-cli — run `qwerty --help` for available commands.');\n return;\n }\n const cfg = await loadConfig();\n const { waitUntilExit } = render(\n createElement(App, { initial: { name: 'main' }, initialCfg: cfg }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n}\n"],"mappings":"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","names":["Command","mkdir","Command","chalk","z","readFile","join","parsed","readFile","join","chalk","Command","Command","chalk","useApp","useInput","jsx","createContext","useContext","useEffect","useState","mkdir","rename","writeFile","join","dirname","request","resolve","join","mkdir","dirname","request","writeFile","rename","jsx","createContext","useState","useEffect","useContext","createContext","useCallback","useContext","useState","jsx","createContext","useState","useCallback","useContext","useState","Box","Text","jsx","jsx","jsxs","useState","Box","Text","useState","useEffect","useRef","Box","Text","useApp","useInput","BigText","z","z","useEffect","useState","useInput","useApp","useState","useApp","useInput","useEffect","useEffect","useRef","useRef","useEffect","useCallback","z","z","useCallback","jsx","jsxs","useState","useEffect","useApp","useRef","useInput","Box","Text","BigText","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","getByPath","useState","useInput","Box","Text","useEffect","useState","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","jsx","useApp","useInput","chalk","Command","Command","chalk","Command","chalk","Command","chalk","readdir","listLocalDictIds","readdir","Command","chalk","render","createElement","render","createElement","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../package.json","../src/commands/config.ts","../src/infra/config-store.ts","../src/infra/paths.ts","../src/infra/fs-store.ts","../src/commands/dict.ts","../src/domain/dictionary.ts","../src/infra/registry-store.ts","../src/infra/dict-downloader.ts","../src/commands/practice.ts","../src/ui/App.tsx","../src/ui/nav.tsx","../src/ui/Fullscreen.tsx","../src/ui/audio-context.tsx","../src/infra/audio.ts","../src/ui/app-state.tsx","../src/ui/screens/MainMenu.tsx","../src/ui/components/BigWord.tsx","../src/ui/screens/PracticeScreen.tsx","../src/util/shuffle.ts","../src/domain/chapters.ts","../src/domain/input-buffer.ts","../src/domain/session.ts","../src/domain/mistakes.ts","../src/ui/hooks/useWordLoop.ts","../src/ui/hooks/useAudio.ts","../src/ui/hooks/useSessionPersistence.ts","../src/domain/stats.ts","../src/ui/screens/DictBrowser.tsx","../src/ui/screens/ConfigEditor.tsx","../src/ui/screens/StatsViewer.tsx","../src/ui/screens/WordLookup.tsx","../src/commands/stats.ts","../src/commands/word.ts","../src/commands/menu.ts"],"sourcesContent":["import { Command } from 'commander';\nimport pkg from '../package.json' with { type: 'json' };\nimport { buildConfigCommand } from './commands/config.js';\nimport { buildDictCommand } from './commands/dict.js';\nimport { buildPracticeCommand } from './commands/practice.js';\nimport { buildStatsCommand } from './commands/stats.js';\nimport { buildWordCommand } from './commands/word.js';\nimport { runMainMenu } from './commands/menu.js';\n\nconst program = new Command();\n\nprogram\n .name('qwerty')\n .description('Terminal clone of qwerty-learner — typing practice for English vocabulary')\n .version(pkg.version);\n\nprogram.addCommand(buildPracticeCommand());\nprogram.addCommand(buildDictCommand());\nprogram.addCommand(buildWordCommand());\nprogram.addCommand(buildStatsCommand());\nprogram.addCommand(buildConfigCommand());\n\nprogram.action(async () => {\n await runMainMenu();\n});\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n","{\n \"name\": \"qwerty-cli\",\n \"version\": \"0.0.1-alpha.5\",\n \"description\": \"Terminal clone of qwerty-learner: typing practice for English vocabulary, with chapters, dictation, mistake book, and audio.\",\n \"type\": \"module\",\n \"bin\": {\n \"qwerty\": \"bin/qwerty.mjs\"\n },\n \"files\": [\n \"dist\",\n \"bin\",\n \"assets\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"sync-registry\": \"tsx scripts/sync-registry.ts\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"keywords\": [\n \"qwerty\",\n \"typing\",\n \"cli\",\n \"vocabulary\",\n \"ink\",\n \"terminal\"\n ],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"ink\": \"^5.0.1\",\n \"ink-big-text\": \"^2.0.0\",\n \"p-queue\": \"^8.0.1\",\n \"react\": \"^18.3.1\",\n \"undici\": \"^6.19.8\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.10\",\n \"@types/react\": \"^18.3.3\",\n \"ts-morph\": \"^23.0.0\",\n \"tsup\": \"^8.2.4\",\n \"tsx\": \"^4.19.0\",\n \"typescript\": \"^5.5.4\",\n \"vitest\": \"^2.0.5\"\n },\n \"pnpm\": {\n \"onlyBuiltDependencies\": [\n \"esbuild\"\n ]\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig, saveConfig, getByPath, setByPath } from '../infra/config-store.js';\n\nexport function buildConfigCommand(): Command {\n const cmd = new Command('config').description('Manage CLI configuration');\n\n cmd\n .command('list')\n .description('Show the effective merged config')\n .action(async () => {\n const cfg = await loadConfig();\n console.log(JSON.stringify(cfg, null, 2));\n });\n\n cmd\n .command('get <key>')\n .description('Get a config value by dotted path (e.g. sounds.keystroke)')\n .action(async (key: string) => {\n const cfg = await loadConfig();\n const v = getByPath(cfg, key);\n if (v === undefined) {\n console.error(chalk.red(`Key not found: ${key}`));\n process.exitCode = 1;\n return;\n }\n console.log(typeof v === 'string' ? v : JSON.stringify(v));\n });\n\n cmd\n .command('set <key> <value>')\n .description('Set a config value by dotted path')\n .action(async (key: string, value: string) => {\n const cfg = await loadConfig();\n const next = setByPath(cfg, key, value);\n await saveConfig(next);\n console.log(chalk.green(`Set ${key} = ${value}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { paths } from './paths.js';\nimport { readJson, writeJsonAtomic } from './fs-store.js';\n\nexport const ConfigSchema = z.object({\n mirror: z.enum(['jsdelivr', 'github']).default('jsdelivr'),\n accent: z.enum(['us', 'uk']).default('us'),\n chapterSize: z.number().int().positive().max(200).default(20),\n sounds: z\n .object({\n master: z.boolean().default(true),\n keystroke: z.boolean().default(true),\n feedback: z.boolean().default(true),\n keySoundName: z.string().default('default'),\n })\n .default({ master: true, keystroke: true, feedback: true, keySoundName: 'default' }),\n autoplayPronunciation: z.boolean().default(true),\n defaultMode: z.enum(['order', 'dictation', 'review', 'random', 'loop']).default('order'),\n defaultDict: z.string().optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nconst DEFAULTS: Config = ConfigSchema.parse({});\n\nexport async function loadConfig(): Promise<Config> {\n const raw = await readJson<unknown>(paths.config);\n if (!raw) return DEFAULTS;\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid config at ${paths.config}: ${result.error.message}`);\n }\n return result.data;\n}\n\nexport async function saveConfig(cfg: Config): Promise<void> {\n await writeJsonAtomic(paths.config, cfg);\n}\n\nexport function getByPath(cfg: Config, path: string): unknown {\n const parts = path.split('.');\n let cur: unknown = cfg;\n for (const p of parts) {\n if (cur === null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nexport function setByPath(cfg: Config, path: string, rawValue: string): Config {\n const parts = path.split('.');\n if (parts.length === 0) throw new Error('Empty config key');\n const clone: Record<string, unknown> = JSON.parse(JSON.stringify(cfg));\n let cur: Record<string, unknown> = clone;\n for (let i = 0; i < parts.length - 1; i++) {\n const k = parts[i]!;\n const next = cur[k];\n if (typeof next !== 'object' || next === null) {\n throw new Error(`Cannot set ${path}: ${parts.slice(0, i + 1).join('.')} is not an object`);\n }\n cur = next as Record<string, unknown>;\n }\n const leaf = parts[parts.length - 1]!;\n cur[leaf] = coerce(rawValue);\n const validated = ConfigSchema.safeParse(clone);\n if (!validated.success) {\n throw new Error(`Invalid value for ${path}: ${validated.error.issues[0]?.message ?? 'unknown'}`);\n }\n return validated.data;\n}\n\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v === 'null') return null;\n if (/^-?\\d+$/.test(v)) return Number(v);\n if (/^-?\\d+\\.\\d+$/.test(v)) return Number(v);\n return v;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\n\nconst ROOT = join(homedir(), '.qwerty-cli');\n\nexport const paths = {\n root: ROOT,\n config: join(ROOT, 'config.json'),\n registry: join(ROOT, 'registry.json'),\n dictsDir: join(ROOT, 'dicts'),\n dictFile: (id: string) => join(ROOT, 'dicts', `${id}.json`),\n dictMeta: (id: string) => join(ROOT, 'dicts', `${id}.meta.json`),\n stats: join(ROOT, 'stats.jsonl'),\n mistakes: join(ROOT, 'mistakes.json'),\n audioCacheDir: join(ROOT, 'cache', 'audio'),\n audioCache: (word: string, accent: 'us' | 'uk') =>\n join(ROOT, 'cache', 'audio', `${encodeURIComponent(word.toLowerCase())}-${accent}.mp3`),\n};\n\nexport async function ensureDirs(): Promise<void> {\n await mkdir(paths.dictsDir, { recursive: true });\n await mkdir(paths.audioCacheDir, { recursive: true });\n}\n\nexport function packageAssetsDir(): string {\n // Works for both bundled (dist/cli.js) and source (src/infra/paths.ts) layouts:\n // 2 levels up from this file lands at the package root.\n const here = fileURLToPath(import.meta.url);\n return resolve(here, '..', '..', 'assets');\n}\n","import { mkdir, readFile, rename, writeFile, appendFile, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJson<T>(path: string): Promise<T | null> {\n try {\n const buf = await readFile(path, 'utf8');\n return JSON.parse(buf) as T;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\nexport async function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n await writeFile(tmp, JSON.stringify(value, null, 2), 'utf8');\n await rename(tmp, path);\n}\n\nexport async function appendJsonl(path: string, line: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(line) + '\\n', 'utf8');\n}\n\nexport async function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const buf = await readFile(path, 'utf8');\n return buf\n .split('\\n')\n .filter((l) => l.trim().length > 0)\n .map((l) => JSON.parse(l) as T);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { filterRegistry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { loadRegistry } from '../infra/registry-store.js';\nimport {\n pullDictionary,\n importDictionary,\n isLocallyAvailable,\n removeDictionary,\n} from '../infra/dict-downloader.js';\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nasync function renderTable(entries: DictionaryEntry[]): Promise<void> {\n const flagged = await Promise.all(\n entries.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n const widths = {\n local: 3,\n id: Math.max(2, ...flagged.map((f) => f.entry.id.length)),\n name: Math.max(4, ...flagged.map((f) => f.entry.name.length)),\n category: Math.max(8, ...flagged.map((f) => f.entry.category.length)),\n length: Math.max(5, ...flagged.map((f) => String(f.entry.length).length)),\n };\n const pad = (s: string, n: number) => s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n const header = [\n pad(' ', widths.local),\n chalk.bold(pad('ID', widths.id)),\n chalk.bold(pad('Name', widths.name)),\n chalk.bold(pad('Category', widths.category)),\n chalk.bold(pad('Words', widths.length)),\n chalk.bold('Description'),\n ].join(' ');\n console.log(header);\n for (const { entry, local } of flagged) {\n const mark = local ? chalk.green(' ✓') : ' ';\n console.log(\n [\n pad(mark, widths.local),\n pad(entry.id, widths.id),\n pad(entry.name, widths.name),\n chalk.dim(pad(entry.category, widths.category)),\n pad(String(entry.length), widths.length),\n chalk.dim(entry.description),\n ].join(' '),\n );\n }\n}\n\n// Naive: count CJK as width-2 for alignment.\nfunction visibleWidth(s: string): number {\n let w = 0;\n // strip ansi\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, '');\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function buildDictCommand(): Command {\n const cmd = new Command('dict').description('Manage dictionaries');\n\n cmd\n .command('list')\n .description('List dictionaries (✓ = locally available)')\n .option('-c, --category <category>', 'filter by category')\n .option('--local-only', 'show only locally downloaded dictionaries')\n .action(async (opts: { category?: string; localOnly?: boolean }) => {\n const reg = await loadRegistry();\n let entries = opts.category\n ? reg.filter((e) => e.category === opts.category)\n : reg;\n if (opts.localOnly) {\n const flags = await Promise.all(entries.map((e) => isLocallyAvailable(e.id)));\n entries = entries.filter((_, i) => flags[i]);\n }\n await renderTable(entries);\n console.log(chalk.dim(`\\n${entries.length} dictionaries`));\n });\n\n cmd\n .command('search <keyword>')\n .description('Search the upstream registry by name/description/category/tags')\n .option('-c, --category <category>', 'restrict to category')\n .option('-l, --language <language>', 'restrict to language')\n .action(async (keyword: string, opts: { category?: string; language?: string }) => {\n const reg = await loadRegistry();\n const matches = filterRegistry(reg, keyword, opts);\n if (matches.length === 0) {\n console.log(chalk.yellow(`No dictionaries matched \"${keyword}\"`));\n return;\n }\n await renderTable(matches);\n console.log(chalk.dim(`\\n${matches.length} matches`));\n });\n\n cmd\n .command('pull <id>')\n .description('Download an upstream dictionary into the local cache')\n .action(async (id: string) => {\n try {\n const { words, size } = await pullDictionary(id);\n console.log(chalk.green(`Saved ${words.length} words (${fmtBytes(size)}) → dict ${chalk.bold(id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('import <file>')\n .description('Import a local qwerty-native JSON dictionary')\n .requiredOption('--id <id>', 'dictionary id (lowercase, digits, dashes)')\n .action(async (file: string, opts: { id: string }) => {\n try {\n const { words, size } = await importDictionary(file, opts.id);\n console.log(chalk.green(`Imported ${words.length} words (${fmtBytes(size)}) as ${chalk.bold(opts.id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('rm <id>')\n .description('Remove a local dictionary')\n .action(async (id: string) => {\n const removed = await removeDictionary(id);\n if (removed) console.log(chalk.green(`Removed ${id}`));\n else console.log(chalk.yellow(`Nothing to remove for ${id}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\n\nexport const DictionaryEntrySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().default(''),\n category: z.string().default(''),\n tags: z.array(z.string()).default([]),\n url: z.string(),\n length: z.number().int().nonnegative().default(0),\n language: z.string().default('en'),\n languageCategory: z.string().default('en'),\n defaultPronIndex: z.number().int().optional(),\n});\n\nexport type DictionaryEntry = z.infer<typeof DictionaryEntrySchema>;\n\nexport const RegistrySchema = z.array(DictionaryEntrySchema);\nexport type Registry = DictionaryEntry[];\n\nexport const WordSchema = z\n .object({\n name: z.string(),\n trans: z.array(z.string()).default([]),\n usphone: z.string().optional(),\n ukphone: z.string().optional(),\n notation: z.string().optional(),\n })\n .passthrough();\n\nexport type Word = z.infer<typeof WordSchema>;\n\nexport const WordArraySchema = z.array(WordSchema);\n\nexport function filterRegistry(\n registry: Registry,\n query: string,\n opts: { category?: string; language?: string } = {},\n): Registry {\n const q = query.trim().toLowerCase();\n return registry.filter((d) => {\n if (opts.category && d.category !== opts.category) return false;\n if (opts.language && d.language !== opts.language) return false;\n if (!q) return true;\n return (\n d.id.toLowerCase().includes(q) ||\n d.name.toLowerCase().includes(q) ||\n d.description.toLowerCase().includes(q) ||\n d.category.toLowerCase().includes(q) ||\n d.tags.some((t) => t.toLowerCase().includes(q))\n );\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { RegistrySchema, type Registry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, packageAssetsDir } from './paths.js';\nimport { readJson } from './fs-store.js';\n\nlet cached: Registry | null = null;\n\nexport async function loadRegistry(): Promise<Registry> {\n if (cached) return cached;\n\n const userOverride = await readJson<unknown>(paths.registry);\n if (userOverride) {\n const parsed = RegistrySchema.safeParse(userOverride);\n if (parsed.success) {\n cached = parsed.data;\n return cached;\n }\n console.warn(`Ignoring corrupt user registry at ${paths.registry}: ${parsed.error.message}`);\n }\n\n const bundled = await readFile(join(packageAssetsDir(), 'registry.snapshot.json'), 'utf8');\n const parsed = RegistrySchema.parse(JSON.parse(bundled));\n cached = parsed;\n return cached;\n}\n\nexport async function findEntry(id: string): Promise<DictionaryEntry | undefined> {\n const reg = await loadRegistry();\n return reg.find((d) => d.id === id);\n}\n","import { createHash } from 'node:crypto';\nimport { stat, copyFile } from 'node:fs/promises';\nimport { request } from 'undici';\nimport { WordArraySchema, type Word, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, ensureDirs } from './paths.js';\nimport { exists, readJson, writeJsonAtomic } from './fs-store.js';\nimport { findEntry } from './registry-store.js';\nimport { loadConfig } from './config-store.js';\n\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/RealKai42/qwerty-learner@master';\nconst GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/RealKai42/qwerty-learner/master';\n\ntype Meta = { sha256: string; size: number; fetchedAt: string; id: string };\n\nasync function fetchWithRetry(url: string, retries = 2): Promise<string> {\n let lastErr: unknown;\n for (let i = 0; i <= retries; i++) {\n try {\n const res = await request(url, { headersTimeout: 10000, bodyTimeout: 30000 });\n if (res.statusCode >= 400) throw new Error(`HTTP ${res.statusCode}`);\n return await res.body.text();\n } catch (err) {\n lastErr = err;\n if (i < retries) await new Promise((r) => setTimeout(r, 500 * (i + 1)));\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n}\n\nfunction buildUrls(mirror: 'jsdelivr' | 'github', relUrl: string): string[] {\n // Registry urls are web-relative (\"/dicts/X.json\"); upstream repo serves them\n // from /public/, so prepend that prefix when hitting source mirrors.\n const path = relUrl.startsWith('/') ? relUrl : `/${relUrl}`;\n const repoPath = `/public${path}`;\n const jsd = `${JSDELIVR_BASE}${repoPath}`;\n const gh = `${GITHUB_RAW_BASE}${repoPath}`;\n return mirror === 'jsdelivr' ? [jsd, gh] : [gh, jsd];\n}\n\nexport async function pullDictionary(id: string): Promise<{ words: Word[]; size: number }> {\n const entry = await findEntry(id);\n if (!entry) throw new Error(`Unknown dictionary id: ${id}`);\n const cfg = await loadConfig();\n await ensureDirs();\n\n const urls = buildUrls(cfg.mirror, entry.url);\n let body: string | null = null;\n let lastErr: unknown;\n for (const u of urls) {\n try {\n body = await fetchWithRetry(u);\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!body) {\n throw new Error(\n `Failed to download dictionary ${id} from any mirror: ${lastErr instanceof Error ? lastErr.message : lastErr}`,\n );\n }\n\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch (err) {\n throw new Error(`Dictionary ${id} is not valid JSON: ${(err as Error).message}`);\n }\n\n const parsed = WordArraySchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(`Dictionary ${id} failed schema validation: ${parsed.error.issues[0]?.message}`);\n }\n\n const sha = createHash('sha256').update(body).digest('hex');\n await writeJsonAtomic(paths.dictFile(id), parsed.data);\n const meta: Meta = { sha256: sha, size: body.length, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size: body.length };\n}\n\nexport async function importDictionary(file: string, id: string): Promise<{ words: Word[]; size: number }> {\n if (!/^[a-z0-9-]+$/.test(id)) {\n throw new Error(`Invalid id \"${id}\". Must match /^[a-z0-9-]+$/`);\n }\n await ensureDirs();\n if (!(await exists(file))) throw new Error(`File not found: ${file}`);\n\n const raw = await readJson<unknown>(file);\n const parsed = WordArraySchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Import rejected: ${parsed.error.issues[0]?.message}`);\n }\n await copyFile(file, paths.dictFile(id));\n const size = (await stat(paths.dictFile(id))).size;\n const sha = createHash('sha256').update(JSON.stringify(parsed.data)).digest('hex');\n const meta: Meta = { sha256: sha, size, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size };\n}\n\nexport async function loadLocalDictionary(id: string): Promise<Word[] | null> {\n const data = await readJson<unknown>(paths.dictFile(id));\n if (!data) return null;\n const parsed = WordArraySchema.safeParse(data);\n if (!parsed.success) throw new Error(`Local dictionary ${id} corrupt: ${parsed.error.message}`);\n return parsed.data;\n}\n\nexport async function isLocallyAvailable(id: string): Promise<boolean> {\n return exists(paths.dictFile(id));\n}\n\nexport async function ensureDictionary(id: string): Promise<Word[]> {\n const local = await loadLocalDictionary(id);\n if (local) return local;\n const { words } = await pullDictionary(id);\n return words;\n}\n\nexport async function removeDictionary(id: string): Promise<boolean> {\n const { unlink } = await import('node:fs/promises');\n let removed = false;\n for (const p of [paths.dictFile(id), paths.dictMeta(id)]) {\n try {\n await unlink(p);\n removed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n return removed;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport type { Mode } from '../domain/chapters.js';\n\nconst MODES: Mode[] = ['order', 'dictation', 'review', 'random', 'loop'];\n\nfunction isMode(v: string): v is Mode {\n return (MODES as string[]).includes(v);\n}\n\nexport async function runPractice(\n dictIdArg: string | undefined,\n options: { chapter?: string | number; mode?: string },\n): Promise<void> {\n if (!process.stdout.isTTY) {\n console.error(chalk.red('Practice requires an interactive TTY.'));\n process.exitCode = 1;\n return;\n }\n const cfg = await loadConfig();\n const dictId = dictIdArg ?? cfg.defaultDict;\n if (!dictId) {\n console.error(chalk.red('No dictionary specified. Pass an id or set config.defaultDict.'));\n process.exitCode = 1;\n return;\n }\n const mode = options.mode ?? cfg.defaultMode;\n if (!isMode(mode)) {\n console.error(chalk.red(`Invalid mode \"${mode}\". Valid: ${MODES.join(', ')}`));\n process.exitCode = 1;\n return;\n }\n const chapterIndex = Math.max(0, Number(options.chapter ?? 1) - 1);\n\n const { waitUntilExit } = render(\n createElement(App, {\n initial: { name: 'practice', params: { dictId, chapterIndex, mode } },\n initialCfg: cfg,\n }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n}\n\nexport function buildPracticeCommand(): Command {\n return new Command('practice')\n .argument('[dictId]', 'dictionary id; falls back to config.defaultDict')\n .description('Start a typing practice session')\n .option('-c, --chapter <n>', 'chapter number (1-based)', '1')\n .option('-m, --mode <mode>', 'order | dictation | review | random | loop')\n .action(async (dictIdArg: string | undefined, options: { chapter: string; mode?: string }) => {\n await runPractice(dictIdArg, options);\n });\n}\n","import { useApp, useInput } from 'ink';\nimport { NavProvider, useNav, type ScreenFrame } from './nav.js';\nimport { Fullscreen } from './Fullscreen.js';\nimport { AudioStatusProvider } from './audio-context.js';\nimport { AppStateProvider, useAppState } from './app-state.js';\nimport { MainMenu } from './screens/MainMenu.js';\nimport { PracticeScreen } from './screens/PracticeScreen.js';\nimport { DictBrowser } from './screens/DictBrowser.js';\nimport { ConfigEditor } from './screens/ConfigEditor.js';\nimport { StatsViewer } from './screens/StatsViewer.js';\nimport { WordLookup } from './screens/WordLookup.js';\nimport type { Config } from '../infra/config-store.js';\n\nexport function App({ initial, initialCfg }: { initial: ScreenFrame; initialCfg: Config }) {\n return (\n <AppStateProvider initialCfg={initialCfg}>\n <AudioStatusProvider disabled={!initialCfg.sounds.master}>\n <NavProvider initial={initial}>\n <Fullscreen>\n <Router />\n </Fullscreen>\n </NavProvider>\n </AudioStatusProvider>\n </AppStateProvider>\n );\n}\n\nfunction Router() {\n const nav = useNav();\n const { cfg } = useAppState();\n const { exit } = useApp();\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') exit();\n });\n\n const frame = nav.current;\n switch (frame.name) {\n case 'main':\n return <MainMenu cfg={cfg} />;\n case 'practice':\n return <PracticeScreen params={frame.params} />;\n case 'dict':\n return <DictBrowser params={frame.params} />;\n case 'config':\n return <ConfigEditor />;\n case 'stats':\n return <StatsViewer />;\n case 'word':\n return <WordLookup />;\n }\n}\n","import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';\n\nexport type ScreenName =\n | 'main'\n | 'practice'\n | 'dict'\n | 'config'\n | 'stats'\n | 'word';\n\nexport type PracticeParams = {\n dictId: string;\n chapterIndex: number;\n mode: 'order' | 'dictation' | 'review' | 'random' | 'loop';\n};\n\nexport type DictParams = {\n pickerMode?: 'set-default' | 'choose-then-practice';\n};\n\nexport type ScreenFrame =\n | { name: 'main' }\n | { name: 'practice'; params: PracticeParams }\n | { name: 'dict'; params?: DictParams }\n | { name: 'config' }\n | { name: 'stats' }\n | { name: 'word' };\n\ntype NavContextValue = {\n current: ScreenFrame;\n stack: ScreenFrame[];\n navigate: (frame: ScreenFrame) => void;\n replace: (frame: ScreenFrame) => void;\n back: () => void;\n reset: (frame: ScreenFrame) => void;\n};\n\nconst NavContext = createContext<NavContextValue | null>(null);\n\nexport function NavProvider({ initial, children }: { initial: ScreenFrame; children: ReactNode }) {\n const [stack, setStack] = useState<ScreenFrame[]>([initial]);\n\n const navigate = useCallback((frame: ScreenFrame) => {\n setStack((s) => [...s, frame]);\n }, []);\n const replace = useCallback((frame: ScreenFrame) => {\n setStack((s) => (s.length === 0 ? [frame] : [...s.slice(0, -1), frame]));\n }, []);\n const back = useCallback(() => {\n setStack((s) => (s.length > 1 ? s.slice(0, -1) : s));\n }, []);\n const reset = useCallback((frame: ScreenFrame) => {\n setStack([frame]);\n }, []);\n\n const current = stack[stack.length - 1]!;\n return (\n <NavContext.Provider value={{ current, stack, navigate, replace, back, reset }}>\n {children}\n </NavContext.Provider>\n );\n}\n\nexport function useNav(): NavContextValue {\n const ctx = useContext(NavContext);\n if (!ctx) throw new Error('useNav must be used inside NavProvider');\n return ctx;\n}\n","import { useEffect, type ReactNode } from 'react';\n\nconst ENTER = '\\x1b[?1049h\\x1b[?25l';\nconst LEAVE = '\\x1b[?25h\\x1b[?1049l';\n\nfunction shouldUse(): boolean {\n return Boolean(process.stdout.isTTY) && process.env.QWERTY_NO_ALTSCREEN !== '1';\n}\n\nexport function Fullscreen({ children }: { children: ReactNode }) {\n useEffect(() => {\n if (!shouldUse()) return;\n process.stdout.write(ENTER);\n\n const leave = () => {\n try {\n process.stdout.write(LEAVE);\n } catch {\n // stream may already be closed\n }\n };\n\n const onSignal = () => {\n leave();\n process.exit(130);\n };\n\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', leave);\n\n return () => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n process.off('exit', leave);\n leave();\n };\n }, []);\n\n return <>{children}</>;\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { initAudio, audioWarning } from '../infra/audio.js';\n\ntype AudioStatus = { warning: string | null; ready: boolean };\n\nconst AudioStatusContext = createContext<AudioStatus>({ warning: null, ready: false });\n\nexport function AudioStatusProvider({\n disabled,\n children,\n}: {\n disabled: boolean;\n children: ReactNode;\n}) {\n const [status, setStatus] = useState<AudioStatus>({ warning: null, ready: false });\n\n useEffect(() => {\n let cancelled = false;\n initAudio(disabled)\n .then(() => {\n if (cancelled) return;\n setStatus({ warning: audioWarning(), ready: true });\n })\n .catch(() => {\n if (cancelled) return;\n setStatus({ warning: null, ready: true });\n });\n return () => {\n cancelled = true;\n };\n }, [disabled]);\n\n return <AudioStatusContext.Provider value={status}>{children}</AudioStatusContext.Provider>;\n}\n\nexport function useAudioStatus(): AudioStatus {\n return useContext(AudioStatusContext);\n}\n","import { spawn } from 'node:child_process';\nimport { access, mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { request } from 'undici';\nimport PQueue from 'p-queue';\nimport { paths, packageAssetsDir, ensureDirs } from './paths.js';\nimport { exists } from './fs-store.js';\n\ntype PlayerKind = 'afplay' | 'paplay' | 'aplay' | 'mpg123' | 'ffplay' | 'powershell';\n\ntype Player = {\n kind: PlayerKind;\n cmd: string;\n args: (file: string) => string[];\n supports: 'wav' | 'mp3' | 'both';\n};\n\nconst CANDIDATES: Player[] = [\n { kind: 'afplay', cmd: 'afplay', args: (f) => [f], supports: 'both' },\n { kind: 'ffplay', cmd: 'ffplay', args: (f) => ['-nodisp', '-autoexit', '-loglevel', 'quiet', f], supports: 'both' },\n { kind: 'mpg123', cmd: 'mpg123', args: (f) => ['-q', f], supports: 'mp3' },\n { kind: 'paplay', cmd: 'paplay', args: (f) => [f], supports: 'wav' },\n { kind: 'aplay', cmd: 'aplay', args: (f) => ['-q', f], supports: 'wav' },\n {\n kind: 'powershell',\n cmd: 'powershell',\n args: (f) => ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${f}').PlaySync();`],\n supports: 'wav',\n },\n];\n\nconst PRON_API = 'https://dict.youdao.com/dictvoice?audio=';\n\ntype AudioRuntime = {\n disabled: boolean;\n wavPlayer: Player | null;\n mp3Player: Player | null;\n warning: string | null;\n keyQueue: PQueue;\n feedbackQueue: PQueue;\n pronQueue: PQueue;\n};\n\nlet runtime: AudioRuntime | null = null;\n\nasync function isExecutable(cmd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const probe = spawn(cmd, ['--version'], { stdio: 'ignore' });\n probe.on('error', () => resolve(false));\n probe.on('exit', () => resolve(true));\n setTimeout(() => {\n probe.kill();\n resolve(false);\n }, 500);\n });\n}\n\nasync function detect(): Promise<{ wav: Player | null; mp3: Player | null }> {\n let wav: Player | null = null;\n let mp3: Player | null = null;\n for (const p of CANDIDATES) {\n if (!(await isExecutable(p.cmd))) continue;\n if (!wav && (p.supports === 'wav' || p.supports === 'both')) wav = p;\n if (!mp3 && (p.supports === 'mp3' || p.supports === 'both')) mp3 = p;\n if (wav && mp3) break;\n }\n return { wav, mp3 };\n}\n\nexport async function initAudio(disabledByConfig: boolean): Promise<AudioRuntime> {\n if (runtime) return runtime;\n if (disabledByConfig) {\n runtime = {\n disabled: true,\n wavPlayer: null,\n mp3Player: null,\n warning: null,\n keyQueue: new PQueue({ concurrency: 1 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n }\n const { wav, mp3 } = await detect();\n let warning: string | null = null;\n if (!wav && !mp3) {\n warning = 'No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.';\n } else if (!mp3) {\n warning = 'No MP3 player found; word pronunciations will be skipped.';\n }\n runtime = {\n disabled: !wav && !mp3,\n wavPlayer: wav,\n mp3Player: mp3,\n warning,\n keyQueue: new PQueue({ concurrency: 2 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n}\n\nfunction spawnPlay(player: Player, file: string): void {\n try {\n const child = spawn(player.cmd, player.args(file), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => {\n // swallow; runtime will be disabled if many failures stack up\n });\n child.unref();\n } catch {\n /* fail-soft */\n }\n}\n\nfunction playFile(file: string, kind: 'wav' | 'mp3'): void {\n if (!runtime || runtime.disabled) return;\n const player = kind === 'wav' ? runtime.wavPlayer : runtime.mp3Player;\n if (!player) return;\n spawnPlay(player, file);\n}\n\nexport function playKeystroke(): void {\n if (!runtime || runtime.disabled) return;\n // Drop if queue is saturated; we never want to delay typing.\n if (runtime.keyQueue.size >= 2) return;\n void runtime.keyQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'key-default.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 30));\n });\n}\n\nexport function playCorrect(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'correct.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nexport function playWrong(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'wrong.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nasync function downloadPronunciation(word: string, accent: 'us' | 'uk'): Promise<string | null> {\n const cacheFile = paths.audioCache(word, accent);\n if (await exists(cacheFile)) return cacheFile;\n await mkdir(dirname(cacheFile), { recursive: true });\n const type = accent === 'us' ? 2 : 1;\n const url = `${PRON_API}${encodeURIComponent(word)}&type=${type}`;\n try {\n const res = await request(url, { headersTimeout: 8000, bodyTimeout: 20000 });\n if (res.statusCode >= 400) return null;\n const buf = Buffer.from(await res.body.arrayBuffer());\n if (buf.length < 1024) return null;\n const tmp = `${cacheFile}.tmp`;\n await writeFile(tmp, buf);\n await rename(tmp, cacheFile);\n return cacheFile;\n } catch {\n return null;\n }\n}\n\nexport async function playPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n await runtime.pronQueue.add(async () => {\n const file = await downloadPronunciation(word, accent);\n if (file) playFile(file, 'mp3');\n });\n}\n\nexport async function prefetchPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n void runtime.pronQueue.add(async () => {\n await downloadPronunciation(word, accent);\n });\n}\n\nexport function audioWarning(): string | null {\n return runtime?.warning ?? null;\n}\n\nexport function audioDisabled(): boolean {\n return runtime?.disabled ?? true;\n}\n","import { createContext, useCallback, useContext, useState, type ReactNode } from 'react';\nimport { saveConfig as persistConfig, type Config } from '../infra/config-store.js';\n\ntype AppState = {\n cfg: Config;\n setCfg: (next: Config) => Promise<void>;\n};\n\nconst AppStateContext = createContext<AppState | null>(null);\n\nexport function AppStateProvider({\n initialCfg,\n children,\n}: {\n initialCfg: Config;\n children: ReactNode;\n}) {\n const [cfg, setCfgState] = useState<Config>(initialCfg);\n const setCfg = useCallback(async (next: Config) => {\n setCfgState(next);\n await persistConfig(next);\n }, []);\n return <AppStateContext.Provider value={{ cfg, setCfg }}>{children}</AppStateContext.Provider>;\n}\n\nexport function useAppState(): AppState {\n const ctx = useContext(AppStateContext);\n if (!ctx) throw new Error('useAppState must be used inside AppStateProvider');\n return ctx;\n}\n","import { useState } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAudioStatus } from '../audio-context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport type { Config } from '../../infra/config-store.js';\n\ntype Item = { key: string; label: string; hint: string; run: () => void };\n\nexport function MainMenu({ cfg }: { cfg: Config }) {\n const [selected, setSelected] = useState(0);\n const { exit } = useApp();\n const nav = useNav();\n const audio = useAudioStatus();\n\n const items: Item[] = [\n {\n key: 'p',\n label: 'Practice',\n hint: cfg.defaultDict ? `start ${cfg.defaultDict}` : 'pick a dictionary',\n run: () => {\n if (cfg.defaultDict) {\n nav.navigate({\n name: 'practice',\n params: { dictId: cfg.defaultDict, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.navigate({ name: 'dict', params: { pickerMode: 'choose-then-practice' } });\n }\n },\n },\n { key: 'd', label: 'Dictionaries', hint: 'browse, pull, set default', run: () => nav.navigate({ name: 'dict' }) },\n { key: 'w', label: 'Word lookup', hint: 'search local dicts', run: () => nav.navigate({ name: 'word' }) },\n { key: 's', label: 'Stats', hint: 'history & trends', run: () => nav.navigate({ name: 'stats' }) },\n { key: 'c', label: 'Config', hint: 'edit preferences', run: () => nav.navigate({ name: 'config' }) },\n { key: 'q', label: 'Quit', hint: 'Ctrl+C also exits', run: () => exit() },\n ];\n\n useInput((input, key) => {\n if (key.upArrow) setSelected((i) => (i - 1 + items.length) % items.length);\n if (key.downArrow) setSelected((i) => (i + 1) % items.length);\n if (key.return) {\n items[selected]!.run();\n return;\n }\n for (const it of items) {\n if (input === it.key) {\n it.run();\n return;\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n qwerty\n </Text>\n <Text color={PALETTE.muted}> · typing practice for the terminal</Text>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n {items.map((it, i) => {\n const active = i === selected;\n return (\n <Box key={it.key}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>[{it.key}]</Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {it.label.padEnd(14)}\n </Text>\n <Text color={PALETTE.muted}>{it.hint}</Text>\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n default dict: {cfg.defaultDict ?? '(none — pick one in Dictionaries)'}\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>↑/↓ navigate · Enter select · letters jump</Text>\n </Box>\n\n {audio.warning && (\n <Box marginTop={1}>\n <Text color={PALETTE.warning}>! {audio.warning}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { Box, Text, useStdout } from 'ink';\nimport BigText from 'ink-big-text';\n\nexport const PALETTE = {\n accent: '#5eead4',\n muted: '#6b7280',\n text: '#e5e7eb',\n primary: '#7dcfff',\n success: '#86efac',\n warning: '#fbbf24',\n error: '#f87171',\n} as const;\n\ntype Props = {\n target: string;\n typed: string;\n error?: boolean;\n hideTarget?: boolean;\n};\n\nexport function BigWord({ target, typed, error = false, hideTarget = false }: Props) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const chars = [...target];\n const typedChars = [...typed];\n\n const useBig = cols >= 60 && process.env.QWERTY_NO_BIGTEXT !== '1';\n\n if (!useBig) {\n return (\n <Box justifyContent=\"center\">\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = isTyped\n ? PALETTE.accent\n : error\n ? PALETTE.error\n : PALETTE.muted;\n return (\n <Text key={i} bold={isTyped} color={color} underline={!isTyped && error}>\n {display}{' '}\n </Text>\n );\n })}\n </Box>\n );\n }\n\n return (\n <Box justifyContent=\"center\" flexDirection=\"row\">\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = isTyped\n ? PALETTE.accent\n : error\n ? PALETTE.error\n : PALETTE.muted;\n return <BigText key={i} text={display} font=\"tiny\" colors={[color]} space={false} />;\n })}\n </Box>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport BigText from 'ink-big-text';\nimport type { Word } from '../../domain/dictionary.js';\nimport type { Mode } from '../../domain/chapters.js';\nimport { chunkChapters, buildPlaylist } from '../../domain/chapters.js';\nimport { sessionSummary } from '../../domain/session.js';\nimport { loadMistakes } from '../../domain/mistakes.js';\nimport { ensureDictionary } from '../../infra/dict-downloader.js';\nimport { useWordLoop } from '../hooks/useWordLoop.js';\nimport { useAudio } from '../hooks/useAudio.js';\nimport { useSessionPersistence } from '../hooks/useSessionPersistence.js';\nimport { useNav, type PracticeParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { BigWord, PALETTE } from '../components/BigWord.js';\n\ntype Phase = 'loading' | 'typing' | 'paused' | 'summary' | 'error';\n\ntype Loaded = {\n playlist: Word[];\n totalChapters: number;\n};\n\nexport function PracticeScreen({ params }: { params: PracticeParams }) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const nav = useNav();\n\n const [phase, setPhase] = useState<Phase>('loading');\n const [loaded, setLoaded] = useState<Loaded | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setPhase('loading');\n setLoaded(null);\n setErrorMsg(null);\n (async () => {\n try {\n const words = await ensureDictionary(dictId);\n if (cancelled) return;\n if (mode === 'review') {\n const book = await loadMistakes();\n if (cancelled) return;\n const reviewWords = words.filter((w) => book[w.name]?.count).slice(0, cfg.chapterSize);\n if (reviewWords.length === 0) {\n setErrorMsg('No mistakes to review yet. Practice some chapters first.');\n setPhase('error');\n return;\n }\n setLoaded({ playlist: reviewWords, totalChapters: 1 });\n setPhase('typing');\n return;\n }\n const chapters = chunkChapters(words, cfg.chapterSize);\n if (chapters.length === 0) {\n setErrorMsg(`Dictionary ${dictId} is empty.`);\n setPhase('error');\n return;\n }\n const idx = Math.max(0, Math.min(chapters.length - 1, chapterIndex));\n const playlist = buildPlaylist(chapters[idx]!, mode);\n setLoaded({ playlist, totalChapters: chapters.length });\n setPhase('typing');\n } catch (err) {\n if (cancelled) return;\n setErrorMsg((err as Error).message);\n setPhase('error');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [dictId, chapterIndex, mode, cfg.chapterSize]);\n\n if (phase === 'loading') {\n return <Centered text=\"loading…\" color={PALETTE.muted} />;\n }\n if (phase === 'error') {\n return <ErrorView msg={errorMsg ?? 'Unknown error'} />;\n }\n if (!loaded) return null;\n\n return (\n <PracticeRunner\n key={`${dictId}-${chapterIndex}-${mode}`}\n params={params}\n loaded={loaded}\n phase={phase}\n setPhase={setPhase}\n />\n );\n}\n\nfunction PracticeRunner({\n params,\n loaded,\n phase,\n setPhase,\n}: {\n params: PracticeParams;\n loaded: Loaded;\n phase: Phase;\n setPhase: (p: Phase) => void;\n}) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const nav = useNav();\n const { exit } = useApp();\n const goBack = () => (nav.stack.length > 1 ? nav.back() : exit());\n const persist = useSessionPersistence({ dictId, chapterIndex, mode });\n\n const audio = useAudio({\n enabled: cfg.sounds.master,\n accent: cfg.accent,\n autoplayPronunciation: cfg.autoplayPronunciation,\n });\n\n const finishedRef = useRef(false);\n const lastEffectRef = useRef<string | null>(null);\n const lastIndexRef = useRef<number>(-1);\n\n const { session, lastEffect, tick } = useWordLoop({\n playlist: loaded.playlist,\n enabled: phase === 'typing',\n onComplete: (s) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n setPhase('summary');\n Promise.resolve(persist(sessionSummary(s))).catch((err) => {\n console.error('Failed to persist session:', err);\n });\n },\n onEscape: () => setPhase(phase === 'paused' ? 'typing' : 'paused'),\n onTab: () => {\n const cur = session.current ? loaded.playlist[session.current.wordIndex] : undefined;\n if (cur) void audio.pronounce(cur.name);\n },\n });\n\n useEffect(() => {\n if (lastEffect === null) return;\n if (lastEffect === lastEffectRef.current) return;\n lastEffectRef.current = lastEffect;\n if (lastEffect === 'wrong' && cfg.sounds.feedback) audio.wrong();\n if (lastEffect === 'progress' && cfg.sounds.keystroke) audio.keystroke();\n if (lastEffect === 'correct') {\n if (cfg.sounds.feedback) audio.correct();\n if (cfg.sounds.keystroke) audio.keystroke();\n }\n }, [lastEffect, audio, cfg.sounds.feedback, cfg.sounds.keystroke]);\n\n useEffect(() => {\n const idx = session.current?.wordIndex ?? -1;\n if (idx === -1) return;\n if (idx === lastIndexRef.current) return;\n lastIndexRef.current = idx;\n const cur = loaded.playlist[idx];\n const next = loaded.playlist[idx + 1];\n if (cur && cfg.autoplayPronunciation) audio.pronounce(cur.name);\n if (next) audio.prefetch(next.name);\n }, [session.current?.wordIndex, audio, cfg.autoplayPronunciation, loaded.playlist]);\n\n void tick;\n\n useInput(\n (input) => {\n if (input === 'r') setPhase('typing');\n if (input === 'q') goBack();\n },\n { isActive: phase === 'paused' },\n );\n\n useInput(\n (input) => {\n if (input === 'q') {\n goBack();\n return;\n }\n if (input === 'n') {\n const nextIdx = chapterIndex + 1;\n if (mode === 'loop') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex, mode } });\n } else if (mode === 'review' || nextIdx >= loaded.totalChapters) {\n goBack();\n } else {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: nextIdx, mode } });\n }\n return;\n }\n if (input === 'm') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: 0, mode: 'review' } });\n return;\n }\n },\n { isActive: phase === 'summary' },\n );\n\n if (phase === 'paused') return <PausedView />;\n if (phase === 'summary') {\n return (\n <SummaryView\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n summary={sessionSummary(session)}\n />\n );\n }\n\n const currentWord = session.current\n ? loaded.playlist[session.current.wordIndex]\n : loaded.playlist[loaded.playlist.length - 1];\n const inputState = session.current?.input ?? { target: '', typed: '', errorsThisWord: 0 };\n const elapsedMs = Date.now() - session.startedAt;\n const completed = session.results.length;\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const minutes = elapsedMs / 60000;\n const wpm = minutes > 0 ? Math.round((completed / minutes) * 10) / 10 : 0;\n\n return (\n <TypingLayout\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n accent={cfg.accent}\n completed={completed}\n total={loaded.playlist.length}\n errors={errors}\n wpm={wpm}\n elapsedMs={elapsedMs}\n target={currentWord?.name ?? ''}\n typed={inputState.typed}\n flashError={lastEffect === 'wrong'}\n hideTarget={mode === 'dictation'}\n phonetic={pickPhonetic(currentWord, cfg.accent)}\n translation={currentWord?.trans ?? []}\n />\n );\n}\n\nfunction pickPhonetic(word: Word | undefined, accent: 'us' | 'uk'): string | null {\n if (!word) return null;\n const p = accent === 'us' ? word.usphone : word.ukphone;\n return p ? `/${p}/` : null;\n}\n\nfunction fmtTime(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction TypingLayout(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n errors: number;\n wpm: number;\n elapsedMs: number;\n target: string;\n typed: string;\n flashError: boolean;\n hideTarget: boolean;\n phonetic: string | null;\n translation: string[];\n}) {\n const progressFrac = props.total === 0 ? 0 : props.completed / props.total;\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <StatusBar\n dictId={props.dictId}\n chapterIndex={props.chapterIndex}\n totalChapters={props.totalChapters}\n mode={props.mode}\n accent={props.accent}\n completed={props.completed}\n total={props.total}\n elapsedMs={props.elapsedMs}\n />\n\n <Box flexGrow={1} flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\">\n <BigWord\n target={props.target}\n typed={props.typed}\n error={props.flashError}\n hideTarget={props.hideTarget}\n />\n\n {props.phonetic && (\n <Box marginTop={1}>\n <Text italic color={PALETTE.muted}>\n {props.phonetic}\n </Text>\n </Box>\n )}\n\n {props.translation.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\" alignItems=\"center\">\n {props.translation.slice(0, 2).map((t, i) => (\n <Text key={i} color={PALETTE.primary}>\n {t}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <ProgressBar frac={progressFrac} />\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n {props.completed}/{props.total} · {fmtTime(props.elapsedMs)} · {props.wpm} wpm · {props.errors} errors\n </Text>\n </Box>\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n Ctrl+N skip · Esc pause · Tab replay · Ctrl+C quit\n </Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nfunction StatusBar(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n elapsedMs: number;\n}) {\n const left =\n props.mode === 'review'\n ? `${props.dictId} · review · ${props.accent}`\n : `${props.dictId} · ch ${props.chapterIndex + 1}/${props.totalChapters} · ${props.mode} · ${props.accent}`;\n const right = `${props.completed}/${props.total} · ${fmtTime(props.elapsedMs)}`;\n return (\n <Box>\n <Text color={PALETTE.muted}>{left}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{right}</Text>\n </Box>\n );\n}\n\nfunction ProgressBar({ frac }: { frac: number }) {\n const cols = process.stdout.columns ?? 80;\n const width = Math.max(20, Math.min(72, cols - 16));\n const filled = Math.round(width * Math.max(0, Math.min(1, frac)));\n const empty = width - filled;\n return (\n <Box justifyContent=\"center\">\n <Text color={PALETTE.accent}>{'━'.repeat(filled)}</Text>\n <Text color={PALETTE.muted}>{'─'.repeat(empty)}</Text>\n </Box>\n );\n}\n\nfunction PausedView() {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <BigText text=\"paused\" font=\"tiny\" colors={[PALETTE.warning]} />\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[r] resume · [q] quit to menu</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ErrorView({ msg }: { msg: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.error}>{msg}</Text>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] back to menu</Text>\n </Box>\n <BackKey />\n </Box>\n );\n}\n\nfunction BackKey() {\n const nav = useNav();\n useInput((input, key) => {\n if (input === 'q' || key.escape) nav.back();\n });\n return null;\n}\n\nfunction Centered({ text, color }: { text: string; color: string }) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={color}>{text}</Text>\n </Box>\n );\n}\n\nfunction SummaryView(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n summary: { wordCount: number; errors: number; durationMs: number; perWordErrors: Record<string, number> };\n}) {\n const { summary } = props;\n const minutes = summary.durationMs / 60000;\n const wpm = minutes > 0 ? Math.round((summary.wordCount / minutes) * 10) / 10 : 0;\n const errorWords = Object.keys(summary.perWordErrors).length;\n const acc = summary.wordCount === 0 ? 1 : Math.max(0, (summary.wordCount - errorWords) / summary.wordCount);\n const accPct = Math.round(acc * 1000) / 10;\n\n const subtitle =\n props.mode === 'review'\n ? `${props.dictId} · review`\n : `${props.dictId} · chapter ${props.chapterIndex + 1}/${props.totalChapters} · ${props.mode}`;\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" paddingY={1} width=\"100%\" height=\"100%\">\n <BigText text=\"complete\" font=\"tiny\" colors={[PALETTE.success]} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{subtitle}</Text>\n </Box>\n\n <Box marginTop={3} flexDirection=\"row\" justifyContent=\"center\">\n <StatCard label=\"words\" value={String(summary.wordCount)} color={PALETTE.text} />\n <StatCard\n label=\"errors\"\n value={String(summary.errors)}\n color={summary.errors > 0 ? PALETTE.error : PALETTE.muted}\n />\n <StatCard label=\"wpm\" value={String(wpm)} color={PALETTE.accent} />\n <StatCard label=\"accuracy\" value={`${accPct}%`} color={PALETTE.accent} />\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>elapsed {fmtTime(summary.durationMs)}</Text>\n </Box>\n\n <Box flexGrow={1} />\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n [n] next chapter · [m] review mistakes · [q] back to menu\n </Text>\n </Box>\n </Box>\n );\n}\n\nfunction StatCard({ label, value, color }: { label: string; value: string; color: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" marginX={2}>\n <BigText text={value} font=\"tiny\" colors={[color]} />\n <Text color={PALETTE.muted}>{label}</Text>\n </Box>\n );\n}\n","export function shuffle<T>(arr: readonly T[], rng: () => number = Math.random): T[] {\n const out = [...arr];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1));\n const tmp = out[i]!;\n out[i] = out[j]!;\n out[j] = tmp;\n }\n return out;\n}\n\nexport function mulberry32(seed: number): () => number {\n let t = seed >>> 0;\n return () => {\n t = (t + 0x6d2b79f5) >>> 0;\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\n r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import type { Word } from './dictionary.js';\nimport { shuffle, mulberry32 } from '../util/shuffle.js';\n\nexport type Mode = 'order' | 'dictation' | 'review' | 'random' | 'loop';\n\nexport function chunkChapters(words: Word[], chapterSize: number): Word[][] {\n if (chapterSize <= 0) throw new Error('chapterSize must be positive');\n const chunks: Word[][] = [];\n for (let i = 0; i < words.length; i += chapterSize) {\n chunks.push(words.slice(i, i + chapterSize));\n }\n return chunks;\n}\n\nexport function chapterCount(totalWords: number, chapterSize: number): number {\n return Math.ceil(totalWords / chapterSize);\n}\n\n/**\n * Build a play list for a chapter, applying the given mode.\n * - order: return as-is\n * - dictation: same as order (hide-the-word behavior is UI-only)\n * - random: single shuffled pass\n * - loop: return as-is; the practice screen drives the repeat\n * - review: caller passes the mistake-book words, we just chunk those\n */\nexport function buildPlaylist(chapter: Word[], mode: Mode, seed?: number): Word[] {\n if (mode === 'random') {\n const rng = seed === undefined ? Math.random : mulberry32(seed);\n return shuffle(chapter, rng);\n }\n return chapter;\n}\n","export type InputState = {\n target: string;\n typed: string;\n errorsThisWord: number;\n};\n\nexport type InputEvent =\n | { type: 'char'; ch: string }\n | { type: 'backspace' }\n | { type: 'reset' };\n\nexport type InputEffect = 'none' | 'progress' | 'wrong' | 'correct' | 'skipped';\n\nexport function initialState(target: string): InputState {\n return { target, typed: '', errorsThisWord: 0 };\n}\n\nexport function reduce(state: InputState, ev: InputEvent): { state: InputState; effect: InputEffect } {\n switch (ev.type) {\n case 'reset':\n return { state: { ...state, typed: '' }, effect: 'none' };\n case 'backspace': {\n if (state.typed.length === 0) return { state, effect: 'none' };\n return { state: { ...state, typed: state.typed.slice(0, -1) }, effect: 'none' };\n }\n case 'char': {\n const candidate = state.typed + ev.ch;\n // Compare by code-point index, not byte length, to handle unicode safely.\n const targetUpToCandidate = [...state.target].slice(0, [...candidate].length).join('');\n if (candidate === targetUpToCandidate) {\n if (candidate.length === state.target.length) {\n return { state: { ...state, typed: candidate }, effect: 'correct' };\n }\n return { state: { ...state, typed: candidate }, effect: 'progress' };\n }\n return {\n state: { ...state, typed: '', errorsThisWord: state.errorsThisWord + 1 },\n effect: 'wrong',\n };\n }\n }\n}\n","import type { Word } from './dictionary.js';\nimport { initialState, reduce, type InputEvent, type InputState, type InputEffect } from './input-buffer.js';\n\nexport type SessionWordResult = { word: string; errors: number; durationMs: number; skipped?: boolean };\n\nexport type Session = {\n startedAt: number;\n results: SessionWordResult[];\n current: { wordIndex: number; wordStartedAt: number; input: InputState } | null;\n finishedAt: number | null;\n playlist: Word[];\n};\n\nexport function startSession(playlist: Word[], now = Date.now()): Session {\n if (playlist.length === 0) {\n return { startedAt: now, results: [], current: null, finishedAt: now, playlist };\n }\n return {\n startedAt: now,\n results: [],\n current: { wordIndex: 0, wordStartedAt: now, input: initialState(playlist[0]!.name) },\n finishedAt: null,\n playlist,\n };\n}\n\nexport function feedSession(session: Session, ev: InputEvent, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const { state, effect } = reduce(session.current.input, ev);\n if (effect === 'correct') {\n const finished: SessionWordResult = {\n word: state.target,\n errors: state.errorsThisWord,\n durationMs: now - session.current.wordStartedAt,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, finished];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect,\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect,\n };\n }\n return {\n session: {\n ...session,\n current: { ...session.current, input: state },\n },\n effect,\n };\n}\n\nexport function skipSession(session: Session, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const result: SessionWordResult = {\n word: session.current.input.target,\n errors: 0,\n durationMs: now - session.current.wordStartedAt,\n skipped: true,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, result];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect: 'skipped',\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect: 'skipped',\n };\n}\n\nexport function sessionSummary(session: Session): {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n} {\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const durationMs =\n (session.finishedAt ?? Date.now()) - session.startedAt;\n const perWordErrors: Record<string, number> = {};\n for (const r of session.results) {\n if (r.errors > 0) perWordErrors[r.word] = (perWordErrors[r.word] ?? 0) + r.errors;\n }\n return { wordCount: session.results.length, errors, durationMs, perWordErrors };\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { readJson, writeJsonAtomic } from '../infra/fs-store.js';\n\nexport const MistakeBookSchema = z.record(\n z.string(),\n z.object({\n count: z.number().int().nonnegative(),\n lastSeen: z.string(),\n dictIds: z.array(z.string()).default([]),\n }),\n);\n\nexport type MistakeBook = z.infer<typeof MistakeBookSchema>;\n\nexport async function loadMistakes(): Promise<MistakeBook> {\n const raw = await readJson<unknown>(paths.mistakes);\n if (!raw) return {};\n const parsed = MistakeBookSchema.safeParse(raw);\n if (!parsed.success) {\n console.warn('Mistake book is corrupt; starting fresh');\n return {};\n }\n return parsed.data;\n}\n\nexport async function saveMistakes(book: MistakeBook): Promise<void> {\n await writeJsonAtomic(paths.mistakes, book);\n}\n\nexport function bump(book: MistakeBook, word: string, dictId: string, delta = 1): MistakeBook {\n const prev = book[word] ?? { count: 0, lastSeen: new Date(0).toISOString(), dictIds: [] };\n const dictIds = prev.dictIds.includes(dictId) ? prev.dictIds : [...prev.dictIds, dictId];\n return {\n ...book,\n [word]: {\n count: prev.count + delta,\n lastSeen: new Date().toISOString(),\n dictIds,\n },\n };\n}\n\nexport function topN(book: MistakeBook, n: number): Array<[string, MistakeBook[string]]> {\n return Object.entries(book)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, n);\n}\n","import { useEffect, useReducer, useRef, useState } from 'react';\nimport { useInput, useApp } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport { startSession, feedSession, skipSession, type Session } from '../../domain/session.js';\nimport type { InputEffect } from '../../domain/input-buffer.js';\n\ntype Action =\n | { type: 'event'; input: string; key: { backspace?: boolean; delete?: boolean; tab?: boolean; escape?: boolean; return?: boolean; ctrl?: boolean }; now: number }\n | { type: 'start'; playlist: Word[]; now: number }\n | { type: 'skip'; now: number };\n\nfunction reducer(state: { session: Session; lastEffect: InputEffect | null }, action: Action) {\n if (action.type === 'start') {\n return { session: startSession(action.playlist, action.now), lastEffect: null };\n }\n if (action.type === 'skip') {\n const r = skipSession(state.session, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.type === 'event') {\n if (action.key.backspace || action.key.delete) {\n const r = feedSession(state.session, { type: 'backspace' }, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.input.length === 0) return state;\n let session = state.session;\n let lastEffect: InputEffect | null = state.lastEffect;\n for (const c of action.input) {\n const r = feedSession(session, { type: 'char', ch: c }, action.now);\n session = r.session;\n lastEffect = r.effect;\n if (session.finishedAt !== null) break;\n }\n return { session, lastEffect };\n }\n return state;\n}\n\nexport type UseWordLoopOpts = {\n playlist: Word[];\n onComplete: (session: Session) => void;\n onTab?: () => void;\n onEscape?: () => void;\n onSkip?: () => void;\n enabled?: boolean;\n};\n\nexport function useWordLoop({ playlist, onComplete, onTab, onEscape, onSkip, enabled = true }: UseWordLoopOpts) {\n const [state, dispatch] = useReducer(reducer, undefined, () => ({\n session: startSession(playlist, Date.now()),\n lastEffect: null as InputEffect | null,\n }));\n const completedRef = useRef(false);\n const [tick, setTick] = useState(0);\n const { exit } = useApp();\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') {\n exit();\n return;\n }\n if (key.ctrl && input === 'n') {\n onSkip?.();\n dispatch({ type: 'skip', now: Date.now() });\n return;\n }\n if (key.escape) {\n onEscape?.();\n return;\n }\n if (key.tab) {\n onTab?.();\n return;\n }\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.return) return;\n if (key.ctrl || key.meta) return;\n const cleaned = [...input].filter((c) => {\n const code = c.codePointAt(0)!;\n return code === 0x20 || (code >= 0x21 && code !== 0x7f);\n }).join('');\n if (cleaned.length === 0) return;\n dispatch({ type: 'event', input: cleaned, key, now: Date.now() });\n },\n { isActive: enabled },\n );\n\n useEffect(() => {\n if (state.session.finishedAt !== null && !completedRef.current) {\n completedRef.current = true;\n onComplete(state.session);\n }\n }, [state.session, onComplete]);\n\n useEffect(() => {\n if (state.session.finishedAt !== null) return;\n const id = setInterval(() => setTick((t) => t + 1), 1000);\n return () => clearInterval(id);\n }, [state.session.finishedAt]);\n\n return { session: state.session, lastEffect: state.lastEffect, tick };\n}\n","import { useEffect, useRef } from 'react';\nimport {\n initAudio,\n playCorrect,\n playWrong,\n playKeystroke,\n playPronunciation,\n prefetchPronunciation,\n} from '../../infra/audio.js';\n\ntype Opts = {\n enabled: boolean;\n accent: 'us' | 'uk';\n autoplayPronunciation: boolean;\n};\n\nexport type AudioControls = {\n keystroke: () => void;\n correct: () => void;\n wrong: () => void;\n pronounce: (word: string) => void;\n prefetch: (word: string) => void;\n};\n\nexport function useAudio(opts: Opts): AudioControls {\n const initedRef = useRef(false);\n useEffect(() => {\n if (initedRef.current) return;\n initedRef.current = true;\n initAudio(!opts.enabled).catch(() => undefined);\n }, [opts.enabled]);\n\n return {\n keystroke: () => opts.enabled && playKeystroke(),\n correct: () => opts.enabled && playCorrect(),\n wrong: () => opts.enabled && playWrong(),\n pronounce: (word) => {\n if (!opts.enabled) return;\n if (opts.autoplayPronunciation) void playPronunciation(word, opts.accent);\n },\n prefetch: (word) => {\n if (!opts.enabled) return;\n void prefetchPronunciation(word, opts.accent);\n },\n };\n}\n","import { useCallback } from 'react';\nimport { appendSession, type SessionRecord } from '../../domain/stats.js';\nimport { loadMistakes, saveMistakes, bump } from '../../domain/mistakes.js';\nimport type { Mode } from '../../domain/chapters.js';\n\ntype Summary = {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\nexport function useSessionPersistence(meta: { dictId: string; chapterIndex: number; mode: Mode }) {\n return useCallback(\n async (summary: Summary): Promise<void> => {\n const rec: SessionRecord = {\n ts: new Date().toISOString(),\n dictId: meta.dictId,\n chapter: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n };\n await appendSession(rec);\n const dirty = Object.entries(summary.perWordErrors).filter(([, n]) => n > 0);\n if (dirty.length === 0) return;\n let book = await loadMistakes();\n for (const [word, n] of dirty) book = bump(book, word, meta.dictId, n);\n await saveMistakes(book);\n },\n [meta.dictId, meta.chapterIndex, meta.mode],\n );\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { appendJsonl, readJsonl } from '../infra/fs-store.js';\n\nexport const SessionRecordSchema = z.object({\n ts: z.string(),\n dictId: z.string(),\n chapter: z.number().int().nonnegative(),\n mode: z.string(),\n wordCount: z.number().int().nonnegative(),\n errors: z.number().int().nonnegative(),\n durationMs: z.number().int().nonnegative(),\n perWordErrors: z.record(z.string(), z.number().int().nonnegative()).default({}),\n});\n\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\nexport async function appendSession(record: SessionRecord): Promise<void> {\n await appendJsonl(paths.stats, record);\n}\n\nexport async function loadSessions(): Promise<SessionRecord[]> {\n const rows = await readJsonl<unknown>(paths.stats);\n return rows\n .map((r) => SessionRecordSchema.safeParse(r))\n .filter((r): r is { success: true; data: SessionRecord } => r.success)\n .map((r) => r.data);\n}\n\nexport function computeWPM(record: SessionRecord): number {\n if (record.durationMs === 0) return 0;\n const minutes = record.durationMs / 60000;\n return Math.round((record.wordCount / minutes) * 10) / 10;\n}\n\nexport function accuracy(record: SessionRecord): number {\n // Word-level: fraction of words finished without any mistake (first-try rate).\n if (record.wordCount === 0) return 1;\n const wordsWithErrors = Object.keys(record.perWordErrors).length;\n return Math.max(0, Math.min(1, (record.wordCount - wordsWithErrors) / record.wordCount));\n}\n\nexport function dailyStreak(sessions: SessionRecord[], now = new Date()): number {\n if (sessions.length === 0) return 0;\n const days = new Set<string>();\n for (const s of sessions) days.add(s.ts.slice(0, 10));\n let streak = 0;\n const cur = new Date(now);\n while (true) {\n const key = cur.toISOString().slice(0, 10);\n if (!days.has(key)) break;\n streak++;\n cur.setUTCDate(cur.getUTCDate() - 1);\n }\n return streak;\n}\n\nconst SPARK = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];\n\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return '';\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = Math.max(1, max - min);\n return values\n .map((v) => {\n const idx = Math.floor(((v - min) / range) * (SPARK.length - 1));\n return SPARK[Math.max(0, Math.min(SPARK.length - 1, idx))]!;\n })\n .join('');\n}\n\nexport type DailyBucket = { date: string; wpm: number; accuracy: number; sessions: number };\n\nexport function dailyBuckets(sessions: SessionRecord[], days: number, now = new Date()): DailyBucket[] {\n const out: DailyBucket[] = [];\n const byDay = new Map<string, SessionRecord[]>();\n for (const s of sessions) {\n const key = s.ts.slice(0, 10);\n const arr = byDay.get(key) ?? [];\n arr.push(s);\n byDay.set(key, arr);\n }\n const cur = new Date(now);\n cur.setUTCDate(cur.getUTCDate() - (days - 1));\n for (let i = 0; i < days; i++) {\n const key = cur.toISOString().slice(0, 10);\n const todays = byDay.get(key) ?? [];\n if (todays.length === 0) {\n out.push({ date: key, wpm: 0, accuracy: 0, sessions: 0 });\n } else {\n const wpm = todays.reduce((a, s) => a + computeWPM(s), 0) / todays.length;\n const acc = todays.reduce((a, s) => a + accuracy(s), 0) / todays.length;\n out.push({ date: key, wpm, accuracy: acc, sessions: todays.length });\n }\n cur.setUTCDate(cur.getUTCDate() + 1);\n }\n return out;\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav, type DictParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { loadRegistry } from '../../infra/registry-store.js';\nimport {\n isLocallyAvailable,\n pullDictionary,\n removeDictionary,\n} from '../../infra/dict-downloader.js';\nimport type { DictionaryEntry } from '../../domain/dictionary.js';\nimport { filterRegistry } from '../../domain/dictionary.js';\n\ntype Row = { entry: DictionaryEntry; local: boolean };\ntype PendingAction =\n | { kind: 'pulling'; id: string }\n | { kind: 'removing'; id: string }\n | { kind: 'error'; id: string; msg: string }\n | null;\n\nexport function DictBrowser({ params }: { params?: DictParams }) {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n const [filter, setFilter] = useState('');\n const [filterFocus, setFilterFocus] = useState(false);\n const [pending, setPending] = useState<PendingAction>(null);\n const [tick, setTick] = useState(0);\n\n const refresh = async () => {\n const reg = await loadRegistry();\n const flagged = await Promise.all(\n reg.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n setRows(flagged);\n setLoading(false);\n };\n\n useEffect(() => {\n void refresh();\n }, [tick]);\n\n const filtered = filter\n ? rows.filter((r) => filterRegistry([r.entry], filter).length > 0)\n : rows;\n const safeSelected = Math.max(0, Math.min(filtered.length - 1, selected));\n const current = filtered[safeSelected];\n\n useInput((input, key) => {\n if (filterFocus) {\n if (key.escape || key.return) {\n setFilterFocus(false);\n return;\n }\n if (key.backspace || key.delete) {\n setFilter((f) => f.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setFilter((f) => f + input);\n }\n return;\n }\n if (key.upArrow) setSelected((i) => Math.max(0, i - 1));\n if (key.downArrow) setSelected((i) => Math.min(filtered.length - 1, i + 1));\n if (input === '/') {\n setFilterFocus(true);\n return;\n }\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (!current) return;\n if (key.return) {\n void (async () => {\n await setCfg({ ...cfg, defaultDict: current.entry.id });\n if (params?.pickerMode === 'choose-then-practice') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.back();\n }\n })();\n return;\n }\n if (input === 'p') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n return;\n }\n if (input === 'r' && current.local) {\n setPending({ kind: 'removing', id: current.entry.id });\n void (async () => {\n try {\n await removeDictionary(current.entry.id);\n setPending(null);\n setTick((t) => t + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n return;\n }\n if (input === 'u') {\n setPending({ kind: 'pulling', id: current.entry.id });\n void (async () => {\n try {\n await pullDictionary(current.entry.id);\n setPending(null);\n setTick((t) => t + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>loading dictionaries…</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n Dictionaries\n </Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>\n {filterFocus ? `/ ${filter}_` : filter ? `/ ${filter}` : `${filtered.length} entries`}\n </Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"60%\">\n {filtered.slice(Math.max(0, safeSelected - 8), safeSelected + 16).map((row, vi) => {\n const i = Math.max(0, safeSelected - 8) + vi;\n const active = i === safeSelected;\n const isDefault = cfg.defaultDict === row.entry.id;\n return (\n <Box key={row.entry.id}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={row.local ? PALETTE.accent : PALETTE.muted}>\n {row.local ? '●' : '○'}\n </Text>\n <Text>{' '}</Text>\n <Text color={isDefault ? PALETTE.success : PALETTE.muted}>\n {isDefault ? '★' : ' '}\n </Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {row.entry.id.slice(0, 14).padEnd(15)}\n </Text>\n <Text color={PALETTE.muted}>\n {String(row.entry.length).padStart(5)}\n </Text>\n </Box>\n );\n })}\n </Box>\n\n <Box flexDirection=\"column\" width=\"40%\" paddingLeft={2}>\n {current && (\n <>\n <Text bold color={PALETTE.text}>\n {current.entry.name}\n </Text>\n <Text color={PALETTE.muted}>{current.entry.id}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>\n {current.entry.language} · {current.entry.category} · {current.entry.length} words\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.primary}>{current.entry.description || '(no description)'}</Text>\n </Box>\n {current.entry.tags.length > 0 && (\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>tags: {current.entry.tags.join(', ')}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text color={current.local ? PALETTE.accent : PALETTE.muted}>\n {current.local ? 'local ✓' : 'not local'}\n </Text>\n {cfg.defaultDict === current.entry.id && (\n <Text color={PALETTE.success}> · default ★</Text>\n )}\n </Box>\n </>\n )}\n </Box>\n </Box>\n\n {pending && (\n <Box marginTop={1}>\n {pending.kind === 'pulling' && (\n <Text color={PALETTE.warning}>pulling {pending.id}…</Text>\n )}\n {pending.kind === 'removing' && (\n <Text color={PALETTE.warning}>removing {pending.id}…</Text>\n )}\n {pending.kind === 'error' && (\n <Text color={PALETTE.error}>error on {pending.id}: {pending.msg}</Text>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>\n ↑/↓ select · Enter set default · p practice · u pull · r remove · / filter · Esc back\n </Text>\n </Box>\n </Box>\n );\n}\n","import { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { setByPath, type Config } from '../../infra/config-store.js';\nimport { PALETTE } from '../components/BigWord.js';\n\ntype FieldSpec =\n | { kind: 'enum'; path: string; label: string; options: string[] }\n | { kind: 'bool'; path: string; label: string }\n | { kind: 'int'; path: string; label: string; min: number; max: number }\n | { kind: 'string'; path: string; label: string }\n | { kind: 'dictRef'; path: 'defaultDict'; label: string };\n\nconst FIELDS: FieldSpec[] = [\n { kind: 'dictRef', path: 'defaultDict', label: 'default dict' },\n { kind: 'enum', path: 'defaultMode', label: 'default mode', options: ['order', 'dictation', 'review', 'random', 'loop'] },\n { kind: 'enum', path: 'accent', label: 'accent', options: ['us', 'uk'] },\n { kind: 'enum', path: 'mirror', label: 'mirror', options: ['jsdelivr', 'github'] },\n { kind: 'int', path: 'chapterSize', label: 'chapter size', min: 1, max: 200 },\n { kind: 'bool', path: 'autoplayPronunciation', label: 'autoplay pronunciation' },\n { kind: 'bool', path: 'sounds.master', label: 'sounds master' },\n { kind: 'bool', path: 'sounds.keystroke', label: 'sounds keystroke' },\n { kind: 'bool', path: 'sounds.feedback', label: 'sounds feedback' },\n { kind: 'string', path: 'sounds.keySoundName', label: 'sounds key sound' },\n];\n\nfunction getByPath(cfg: Config, path: string): unknown {\n return path.split('.').reduce<unknown>((acc, k) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[k];\n return undefined;\n }, cfg);\n}\n\nexport function ConfigEditor() {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const [selected, setSelected] = useState(0);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const field = FIELDS[selected]!;\n const currentValue = getByPath(cfg, field.path);\n\n const commit = async (raw: string) => {\n try {\n const next = setByPath(cfg, field.path, raw);\n await setCfg(next);\n setEditing(false);\n setError(null);\n } catch (err) {\n setError((err as Error).message);\n }\n };\n\n useInput((input, key) => {\n if (editing && field.kind === 'string') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) setDraft((d) => d + input);\n return;\n }\n if (editing && field.kind === 'int') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (/^[0-9]$/.test(input)) setDraft((d) => d + input);\n return;\n }\n\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => (i - 1 + FIELDS.length) % FIELDS.length);\n setError(null);\n return;\n }\n if (key.downArrow) {\n setSelected((i) => (i + 1) % FIELDS.length);\n setError(null);\n return;\n }\n if (field.kind === 'bool' && (input === ' ' || key.return)) {\n void commit(currentValue ? 'false' : 'true');\n return;\n }\n if (field.kind === 'enum' && (key.leftArrow || key.rightArrow)) {\n const idx = field.options.indexOf(String(currentValue));\n const delta = key.rightArrow ? 1 : -1;\n const next = field.options[(idx + delta + field.options.length) % field.options.length]!;\n void commit(next);\n return;\n }\n if (field.kind === 'dictRef' && key.return) {\n nav.navigate({ name: 'dict', params: { pickerMode: 'set-default' } });\n return;\n }\n if ((field.kind === 'string' || field.kind === 'int') && key.return) {\n setDraft(String(currentValue ?? ''));\n setEditing(true);\n setError(null);\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n Config\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {FIELDS.map((f, i) => {\n const active = i === selected;\n const value = getByPath(cfg, f.path);\n const display = renderValue(f, value, active && editing ? draft : null);\n return (\n <Box key={f.path}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {f.label.padEnd(28)}\n </Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{display}</Text>\n </Box>\n );\n })}\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>! {error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{hintFor(field, editing)}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction renderValue(field: FieldSpec, value: unknown, draft: string | null): string {\n if (draft !== null) return `${draft}_`;\n if (field.kind === 'bool') return value ? '✓ on' : '✗ off';\n if (field.kind === 'dictRef') return String(value ?? '(none)');\n if (field.kind === 'enum') return `< ${value} >`;\n return String(value ?? '');\n}\n\nfunction hintFor(field: FieldSpec, editing: boolean): string {\n if (editing) return 'type to edit · Enter save · Esc cancel';\n if (field.kind === 'bool') return 'space toggle · ↑/↓ move · Esc back';\n if (field.kind === 'enum') return '←/→ cycle · ↑/↓ move · Esc back';\n if (field.kind === 'dictRef') return 'Enter pick dict · ↑/↓ move · Esc back';\n return 'Enter edit · ↑/↓ move · Esc back';\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport {\n loadSessions,\n computeWPM,\n accuracy,\n dailyBuckets,\n sparkline,\n dailyStreak,\n type SessionRecord,\n} from '../../domain/stats.js';\nimport { loadMistakes, topN, type MistakeBook } from '../../domain/mistakes.js';\n\nconst DAY_WINDOWS = [7, 14, 30, 90];\n\nexport function StatsViewer() {\n const nav = useNav();\n const [sessions, setSessions] = useState<SessionRecord[] | null>(null);\n const [book, setBook] = useState<MistakeBook | null>(null);\n const [windowIdx, setWindowIdx] = useState(1);\n\n useEffect(() => {\n void (async () => {\n const [s, b] = await Promise.all([loadSessions(), loadMistakes()]);\n setSessions(s);\n setBook(b);\n })();\n }, []);\n\n useInput((input, key) => {\n if (key.escape || input === 'b' || input === 'q') {\n nav.back();\n return;\n }\n if (input === 'n') setWindowIdx((i) => (i + 1) % DAY_WINDOWS.length);\n if (input === 'N') setWindowIdx((i) => (i - 1 + DAY_WINDOWS.length) % DAY_WINDOWS.length);\n });\n\n if (!sessions || !book) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>loading stats…</Text>\n </Box>\n );\n }\n\n if (sessions.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>No practice history yet.</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>Run a practice session first.</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] back</Text>\n </Box>\n </Box>\n );\n }\n\n const days = DAY_WINDOWS[windowIdx]!;\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n const recent = sessions.slice(-5).reverse();\n const top = topN(book, 8);\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n Stats\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={PALETTE.muted}>lifetime</Text>\n <Box marginTop={1}>\n <Stat label=\"sessions\" value={String(sessions.length)} />\n <Stat label=\"words\" value={String(totalWords)} />\n <Stat label=\"errors\" value={String(totalErrors)} />\n <Stat label=\"wpm\" value={String(overallWpm)} accent />\n <Stat label=\"accuracy\" value={`${Math.round(overallAcc * 1000) / 10}%`} accent />\n <Stat label=\"streak\" value={`${streak}d`} accent />\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>last {days} days (n / N to cycle window)</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text color={PALETTE.muted}>{'wpm '.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.wpm))}</Text>\n <Text color={PALETTE.muted}> max {Math.round(Math.max(...buckets.map((b) => b.wpm)))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{'accuracy'.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.accuracy * 100))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{'sessions'.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.sessions))}</Text>\n </Box>\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>recent sessions</Text>\n {recent.map((s, i) => (\n <Box key={i}>\n <Text color={PALETTE.muted}> {s.ts.replace('T', ' ').slice(0, 16)} </Text>\n <Text color={PALETTE.text}>{s.dictId.padEnd(14)}</Text>\n <Text color={PALETTE.muted}>\n {' '}ch{String(s.chapter + 1).padStart(3)} {s.mode.padEnd(9)} {String(s.wordCount).padStart(3)}w {s.errors}err {computeWPM(s)}wpm {Math.round(accuracy(s) * 1000) / 10}%\n </Text>\n </Box>\n ))}\n </Box>\n\n {top.length > 0 && (\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>top mistakes</Text>\n {top.map(([word, entry]) => (\n <Box key={word}>\n <Text color={PALETTE.error}> {String(entry.count).padStart(3)} </Text>\n <Text color={PALETTE.text}>{word.padEnd(20)}</Text>\n <Text color={PALETTE.muted}>{entry.dictIds.join(', ')}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n <Box flexGrow={1} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>n / N cycle window · q back</Text>\n </Box>\n </Box>\n );\n}\n\nfunction Stat({ label, value, accent = false }: { label: string; value: string; accent?: boolean }) {\n return (\n <Box marginRight={3}>\n <Text color={PALETTE.muted}>{label} </Text>\n <Text bold color={accent ? PALETTE.accent : PALETTE.text}>\n {value}\n </Text>\n </Box>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../../infra/paths.js';\nimport { loadLocalDictionary } from '../../infra/dict-downloader.js';\nimport { loadMistakes, type MistakeBook } from '../../domain/mistakes.js';\nimport type { Word } from '../../domain/dictionary.js';\n\ntype Hit = { dictId: string; word: Word };\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function WordLookup() {\n const nav = useNav();\n const [query, setQuery] = useState('');\n const [allWords, setAllWords] = useState<Hit[]>([]);\n const [book, setBook] = useState<MistakeBook>({});\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n\n useEffect(() => {\n void (async () => {\n const ids = await listLocalDictIds();\n const collected: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) collected.push({ dictId: id, word: w });\n }\n setAllWords(collected);\n setBook(await loadMistakes());\n setLoading(false);\n })();\n }, []);\n\n const q = query.toLowerCase().trim();\n const filtered = q\n ? allWords.filter((h) => h.word.name.toLowerCase().includes(q)).slice(0, 50)\n : [];\n\n useInput((input, key) => {\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setSelected((i) => Math.min(filtered.length - 1, i + 1));\n return;\n }\n if (key.backspace || key.delete) {\n setQuery((s) => s.slice(0, -1));\n setSelected(0);\n return;\n }\n if (input && !key.ctrl && !key.meta && input.trim().length > 0) {\n setQuery((s) => s + input);\n setSelected(0);\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>indexing local dictionaries…</Text>\n </Box>\n );\n }\n\n if (allWords.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>No local dictionaries.</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>Pull one in Dictionaries first.</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[Esc] back</Text>\n </Box>\n </Box>\n );\n }\n\n const current = filtered[selected];\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>Word lookup</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{allWords.length} words across local dicts</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{'> '}</Text>\n <Text color={PALETTE.text}>{query}</Text>\n <Text color={PALETTE.accent}>_</Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"40%\">\n {filtered.map((h, i) => {\n const active = i === selected;\n return (\n <Box key={`${h.dictId}-${h.word.name}-${i}`}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {h.word.name.padEnd(20)}\n </Text>\n <Text color={PALETTE.muted}>{h.dictId}</Text>\n </Box>\n );\n })}\n {filtered.length === 0 && q && (\n <Text color={PALETTE.muted}>no matches for \"{query}\"</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" width=\"60%\" paddingLeft={2}>\n {current && (\n <>\n <Text bold color={PALETTE.text}>{current.word.name}</Text>\n <Box marginTop={1}>\n {current.word.usphone && (\n <Text color={PALETTE.muted}>US /{current.word.usphone}/ </Text>\n )}\n {current.word.ukphone && (\n <Text color={PALETTE.muted}>UK /{current.word.ukphone}/</Text>\n )}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {(current.word.trans ?? []).map((t, i) => (\n <Text key={i} color={PALETTE.primary}>· {t}</Text>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>in: {current.dictId}</Text>\n </Box>\n {book[current.word.name] && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>\n mistakes: {book[current.word.name]!.count}\n </Text>\n <Text color={PALETTE.muted}>\n {' '}(last {book[current.word.name]!.lastSeen.slice(0, 10)})\n </Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>type to filter · ↑/↓ select · Esc back</Text>\n </Box>\n </Box>\n );\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadSessions, computeWPM, accuracy, dailyBuckets, sparkline, dailyStreak } from '../domain/stats.js';\nimport { loadMistakes, topN } from '../domain/mistakes.js';\n\nexport function buildStatsCommand(): Command {\n return new Command('stats')\n .description('Show practice history and trends')\n .option('-d, --days <n>', 'window size for trend (default 14)', '14')\n .option('--top <n>', 'how many top mistakes to show (default 10)', '10')\n .action(async (opts: { days: string; top: string }) => {\n const days = Math.max(1, Number(opts.days) || 14);\n const topCount = Math.max(1, Number(opts.top) || 10);\n const sessions = await loadSessions();\n const book = await loadMistakes();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No practice history yet. Run `qwerty practice <dict>` to get started.'));\n return;\n }\n\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n console.log(chalk.bold('\\nLifetime'));\n console.log(` ${chalk.dim('sessions')} ${sessions.length} ${chalk.dim('words')} ${totalWords} ${chalk.dim('errors')} ${totalErrors}`);\n console.log(` ${chalk.dim('avg wpm')} ${overallWpm} ${chalk.dim('avg accuracy')} ${Math.round(overallAcc * 1000) / 10}% ${chalk.dim('streak')} ${chalk.bold(streak)}d`);\n\n console.log(chalk.bold(`\\nLast ${days} days`));\n console.log(` ${chalk.dim('wpm ')} ${sparkline(buckets.map((b) => b.wpm))} ${chalk.dim('max')} ${Math.round(Math.max(...buckets.map((b) => b.wpm)))}`);\n console.log(` ${chalk.dim('accuracy')} ${sparkline(buckets.map((b) => b.accuracy * 100))} ${chalk.dim('range')} ${Math.round(Math.min(...buckets.map((b) => b.accuracy * 100)))}-${Math.round(Math.max(...buckets.map((b) => b.accuracy * 100)))}%`);\n console.log(` ${chalk.dim('sessions')} ${sparkline(buckets.map((b) => b.sessions))}`);\n\n const recent = sessions.slice(-5).reverse();\n console.log(chalk.bold('\\nLast 5 sessions'));\n for (const s of recent) {\n const wpm = computeWPM(s);\n const acc = Math.round(accuracy(s) * 1000) / 10;\n console.log(\n ` ${chalk.dim(s.ts.replace('T', ' ').slice(0, 16))} ${chalk.cyan(s.dictId.padEnd(14))} ch${String(s.chapter + 1).padStart(3)} ${s.mode.padEnd(9)} ${String(s.wordCount).padStart(3)}w ${s.errors}err ${wpm}wpm ${acc}%`,\n );\n }\n\n const top = topN(book, topCount);\n if (top.length > 0) {\n console.log(chalk.bold(`\\nTop ${top.length} mistakes`));\n for (const [word, entry] of top) {\n console.log(` ${chalk.red(String(entry.count).padStart(3))} ${chalk.bold(word.padEnd(20))} ${chalk.dim(entry.dictIds.join(', '))}`);\n }\n } else {\n console.log(chalk.bold('\\nTop mistakes'));\n console.log(chalk.dim(' none — keep going'));\n }\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../infra/paths.js';\nimport { loadLocalDictionary } from '../infra/dict-downloader.js';\nimport { loadMistakes } from '../domain/mistakes.js';\nimport { findEntry } from '../infra/registry-store.js';\nimport type { Word } from '../domain/dictionary.js';\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function buildWordCommand(): Command {\n return new Command('word')\n .argument('<keyword>')\n .description('Look up a word across local dictionaries')\n .option('--exact', 'require exact (case-insensitive) match')\n .action(async (keyword: string, opts: { exact?: boolean }) => {\n const q = keyword.toLowerCase();\n const ids = await listLocalDictIds();\n if (ids.length === 0) {\n console.log(chalk.yellow('No local dictionaries. Run `qwerty dict pull <id>` first.'));\n return;\n }\n\n type Hit = { dictId: string; word: Word };\n const hits: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) {\n const wl = w.name.toLowerCase();\n const match = opts.exact ? wl === q : wl.includes(q);\n if (match) hits.push({ dictId: id, word: w });\n }\n }\n\n if (hits.length === 0) {\n console.log(chalk.yellow(`No matches for \"${keyword}\" in ${ids.length} local dictionaries`));\n return;\n }\n\n // Group hits by word name; one block per distinct word.\n const byName = new Map<string, Hit[]>();\n for (const h of hits) {\n const arr = byName.get(h.word.name) ?? [];\n arr.push(h);\n byName.set(h.word.name, arr);\n }\n\n const book = await loadMistakes();\n for (const [name, group] of byName) {\n const first = group[0]!.word;\n console.log();\n console.log(chalk.bold.white(name));\n const us = first.usphone ? `US /${first.usphone}/` : '';\n const uk = first.ukphone ? `UK /${first.ukphone}/` : '';\n if (us || uk) console.log(chalk.dim(` ${[us, uk].filter(Boolean).join(' ')}`));\n for (const t of first.trans ?? []) console.log(chalk.cyan(` · ${t}`));\n const sources = await Promise.all(\n group.map(async (h) => {\n const reg = await findEntry(h.dictId);\n return reg?.name ?? h.dictId;\n }),\n );\n console.log(chalk.dim(` in: ${sources.join(', ')}`));\n const mistake = book[name];\n if (mistake) {\n console.log(chalk.dim(` mistakes: ${mistake.count} (last ${mistake.lastSeen.slice(0, 10)})`));\n }\n }\n console.log();\n });\n}\n","import { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\n\nexport async function runMainMenu(): Promise<void> {\n if (!process.stdout.isTTY) {\n console.log('qwerty-cli — run `qwerty --help` for available commands.');\n return;\n }\n const cfg = await loadConfig();\n const { waitUntilExit } = render(\n createElement(App, { initial: { name: 'main' }, initialCfg: cfg }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n}\n"],"mappings":"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","names":["Command","mkdir","Command","chalk","z","readFile","join","parsed","readFile","join","chalk","Command","Command","chalk","useApp","useInput","jsx","createContext","useContext","useEffect","useState","mkdir","rename","writeFile","join","dirname","request","resolve","join","mkdir","dirname","request","writeFile","rename","jsx","createContext","useState","useEffect","useContext","createContext","useCallback","useContext","useState","jsx","createContext","useState","useCallback","useContext","useState","Box","Text","jsx","jsx","jsxs","useState","Box","Text","useState","useEffect","useRef","Box","Text","useApp","useInput","BigText","z","z","useEffect","useState","useInput","useApp","useState","useApp","useInput","useEffect","useEffect","useRef","useRef","useEffect","useCallback","z","z","useCallback","jsx","jsxs","useState","useEffect","useApp","useRef","useInput","Box","Text","BigText","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","getByPath","useState","useInput","Box","Text","useEffect","useState","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","jsx","useApp","useInput","chalk","Command","Command","chalk","Command","chalk","Command","chalk","readdir","listLocalDictIds","readdir","Command","chalk","render","createElement","render","createElement","Command"]}
|
package/package.json
CHANGED