@qnroa/qtype 0.0.1

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/CHANGELOG.zh.md +82 -0
  3. package/LICENSE +201 -0
  4. package/README.md +113 -0
  5. package/README.zh.md +114 -0
  6. package/dist/cli/bootstrap.js +190 -0
  7. package/dist/cli/commands/check/action.js +56 -0
  8. package/dist/cli/commands/check/i18n.js +26 -0
  9. package/dist/cli/commands/check/index.js +20 -0
  10. package/dist/cli/commands/config/action.js +236 -0
  11. package/dist/cli/commands/config/i18n.js +64 -0
  12. package/dist/cli/commands/config/index.js +72 -0
  13. package/dist/cli/commands/content/index.js +22 -0
  14. package/dist/cli/commands/content/lint/action.js +102 -0
  15. package/dist/cli/commands/content/lint/i18n.js +32 -0
  16. package/dist/cli/commands/content/lint/index.js +19 -0
  17. package/dist/cli/commands/content/search/action.js +64 -0
  18. package/dist/cli/commands/content/search/i18n.js +20 -0
  19. package/dist/cli/commands/content/search/index.js +24 -0
  20. package/dist/cli/commands/content/validate/action.js +145 -0
  21. package/dist/cli/commands/content/validate/i18n.js +32 -0
  22. package/dist/cli/commands/content/validate/index.js +19 -0
  23. package/dist/cli/commands/index.js +19 -0
  24. package/dist/cli/commands/init/index.js +53 -0
  25. package/dist/cli/commands/pack/i18n.js +20 -0
  26. package/dist/cli/commands/pack/index.js +48 -0
  27. package/dist/cli/commands/plugin/i18n.js +28 -0
  28. package/dist/cli/commands/plugin/index.js +41 -0
  29. package/dist/cli/commands/publish/build/action.js +208 -0
  30. package/dist/cli/commands/publish/build/i18n.js +50 -0
  31. package/dist/cli/commands/publish/build/index.js +24 -0
  32. package/dist/cli/commands/publish/build/mermaidPass.js +93 -0
  33. package/dist/cli/commands/publish/build/mermaidPrerender.js +199 -0
  34. package/dist/cli/commands/publish/index.js +21 -0
  35. package/dist/cli/commands/publish/init/action.js +74 -0
  36. package/dist/cli/commands/publish/init/i18n.js +22 -0
  37. package/dist/cli/commands/publish/init/index.js +26 -0
  38. package/dist/cli/commands/publish/password/action.js +158 -0
  39. package/dist/cli/commands/publish/password/i18n.js +44 -0
  40. package/dist/cli/commands/publish/password/index.js +35 -0
  41. package/dist/cli/commands/publish/serve/action.js +117 -0
  42. package/dist/cli/commands/publish/serve/i18n.js +32 -0
  43. package/dist/cli/commands/publish/serve/index.js +37 -0
  44. package/dist/cli/commands/repo/index.js +19 -0
  45. package/dist/cli/commands/repo/new/action.js +98 -0
  46. package/dist/cli/commands/repo/new/i18n.js +46 -0
  47. package/dist/cli/commands/repo/new/index.js +57 -0
  48. package/dist/cli/commands/repo/sync/action.js +202 -0
  49. package/dist/cli/commands/repo/sync/i18n.js +44 -0
  50. package/dist/cli/commands/repo/sync/index.js +47 -0
  51. package/dist/cli/commands/repo/templates.js +87 -0
  52. package/dist/cli/i18n/index.js +141 -0
  53. package/dist/cli/i18n/shared.js +142 -0
  54. package/dist/cli/index.js +79 -0
  55. package/dist/cli/registry/command.js +1 -0
  56. package/dist/cli/registry/commander-i18n.js +76 -0
  57. package/dist/cli/registry/help.js +142 -0
  58. package/dist/cli/registry/mount.js +71 -0
  59. package/dist/cli/utils/output.js +92 -0
  60. package/dist/cli/utils/paths.js +13 -0
  61. package/dist/cli/utils/prompt.js +72 -0
  62. package/dist/cli/utils/repoGuard.js +41 -0
  63. package/dist/core/encrypt.js +113 -0
  64. package/dist/core/index.js +8 -0
  65. package/dist/core/keystroke/asciiMap.js +39 -0
  66. package/dist/core/keystroke/chineseMap.js +32 -0
  67. package/dist/core/keystroke/fullwidthMap.js +41 -0
  68. package/dist/core/keystroke/index.js +22 -0
  69. package/dist/core/keystroke/textNormalize.js +68 -0
  70. package/dist/core/keystroke/types.js +1 -0
  71. package/dist/core/parser/frontmatter.js +58 -0
  72. package/dist/core/parser/index.js +2 -0
  73. package/dist/core/parser/parseMaterial.js +42 -0
  74. package/dist/core/types.js +1 -0
  75. package/dist/core/typing/engine.js +112 -0
  76. package/dist/core/typing/index.js +2 -0
  77. package/dist/core/typing/metrics.js +20 -0
  78. package/dist/store/index.js +44 -0
  79. package/dist/store/kv.js +276 -0
  80. package/dist/store/storage/browser.js +61 -0
  81. package/dist/store/storage/json.js +113 -0
  82. package/dist/store/storage/memory.js +24 -0
  83. package/dist/store/types.js +47 -0
  84. package/dist/store/validators.js +71 -0
  85. package/dist/view/assets/index-DBABH3dG.js +111 -0
  86. package/dist/view/assets/index-RTLZ-zOC.css +1 -0
  87. package/dist/view/index.html +14 -0
  88. package/dist/view/qtype-logo.svg +49 -0
  89. package/dist/view/qtype-mark.svg +21 -0
  90. package/docs/README.md +23 -0
  91. package/docs/README.zh.md +20 -0
  92. package/docs/en/authoring.md +138 -0
  93. package/docs/en/cli-reference.md +171 -0
  94. package/docs/zh/authoring.md +131 -0
  95. package/docs/zh/cli-reference.md +162 -0
  96. package/package.json +85 -0
  97. package/templates/en/QTYPE.md +618 -0
  98. package/templates/en/README.md +64 -0
  99. package/templates/en/TODO.md +7 -0
  100. package/templates/en/index.md +7 -0
  101. package/templates/en/log.md +3 -0
  102. package/templates/en/material/.gitkeep +0 -0
  103. package/templates/en/material/example.md +47 -0
  104. package/templates/zh/QTYPE.md +618 -0
  105. package/templates/zh/README.md +64 -0
  106. package/templates/zh/TODO.md +7 -0
  107. package/templates/zh/index.md +7 -0
  108. package/templates/zh/log.md +3 -0
  109. package/templates/zh/material/.gitkeep +0 -0
  110. package/templates/zh/material/example.md +47 -0
@@ -0,0 +1,131 @@
1
+ # 撰写 material 文件
2
+
3
+ English: [authoring.md](../en/authoring.md)
4
+
5
+ `material/*.md` 的快速入门。权威规范见
6
+ [`templates/zh/QTYPE.md`](../../templates/zh/QTYPE.md)
7
+ (`qtype init --lang zh` 时拷到新 repo)。有疑问先查那份。
8
+
9
+ ## 文件位置
10
+
11
+ ```
12
+ my-deck/
13
+ ├── QTYPE.md # 规范(init 时自动拷贝;留着)
14
+ ├── index.md # 面向人的目录(可选)
15
+ ├── material/
16
+ │ ├── example.md
17
+ │ ├── javascript-basics.md
18
+ │ └── english-vocab.md
19
+ └── .qtype/
20
+ └── config.json # 单 repo 配置
21
+ ```
22
+
23
+ 一个 `.md` 文件 = 一副卡组。
24
+
25
+ ## 卡片形状
26
+
27
+ 每张卡有一个问题和一个答案,用 `## Q:` / `## A:` 标题分隔。同一文件里
28
+ 的多张卡用 `\n\n---\n\n`(独占一行的 `---`,前后各留空行)分隔。
29
+
30
+ ```markdown
31
+ ---
32
+ tags: [js, basics]
33
+ type: normal
34
+ ---
35
+
36
+ ## Q:
37
+
38
+ React 三大核心概念是什么?
39
+
40
+ ## A:
41
+
42
+ 组件、props 和 state。
43
+
44
+ ---
45
+
46
+ ## Q:
47
+
48
+ `useState` 返回什么?
49
+
50
+ ## A:
51
+
52
+ 一个 `[值, setter]` 的元组。
53
+ ```
54
+
55
+ parser 先按 `---` 分割,再逐卡提取 Q、A、metadata。缺 Q 或 A 的卡片被
56
+ 静默丢弃(方便写占位)。
57
+
58
+ ## Frontmatter 字段
59
+
60
+ 文件顶部的 YAML frontmatter 对文件内每张卡都生效。如需单卡覆盖,把
61
+ YAML fence 放到该卡上方(见规范)。
62
+
63
+ | 字段 | 类型 | 说明 |
64
+ |---|---|---|
65
+ | `tags` | `string[]` | 自由形式;用于列表过滤 |
66
+ | `type` | `normal \| word \| sentence` | 默认 `normal` |
67
+ | `hint` | `none \| ghost` | 下方是否显示褪色目标 |
68
+ | `difficulty` | `1..5` | 可选,信息用 |
69
+ | `phonetic` | `string` | `type: word` 用 —— IPA / 拼音 |
70
+ | `gloss` | `string` | `type: word` 用 —— 释义 |
71
+ | `translation` | `string` | `type: sentence` 用 —— 目标语等价句 |
72
+
73
+ 示例 —— 一张 `word` 卡:
74
+
75
+ ```markdown
76
+ ---
77
+ type: word
78
+ phonetic: /ˈklō-zhər/
79
+ gloss: 捕获词法作用域的函数
80
+ ---
81
+
82
+ ## Q:
83
+
84
+ closure
85
+
86
+ ## A:
87
+
88
+ closure
89
+ ```
90
+
91
+ ## 被打字的是什么?
92
+
93
+ **答案**是用户要打的内容。Q 只做提示(不打)。代码块、行内代码、多行
94
+ 答案都支持 —— 打字引擎按归一化后的答案逐 codepoint 迭代。
95
+
96
+ 引擎处理不了的字符(比如某些代理对 emoji)会出现在 `qtype check`
97
+ 输出里。发布前修掉或删掉。
98
+
99
+ ## 跑 `qtype check`
100
+
101
+ 发布前始终跑:
102
+
103
+ ```bash
104
+ qtype check
105
+ ```
106
+
107
+ 它报告:
108
+ - `material/` 目录不存在(致命)
109
+ - 含无法打字字符的卡片(致命,附逐卡列表)
110
+
111
+ 退出码 0 = 可以安全发布。
112
+
113
+ ## 发布
114
+
115
+ ```bash
116
+ qtype publish build
117
+ qtype publish serve # http://localhost:4000
118
+ ```
119
+
120
+ 密码保护的卡组:
121
+
122
+ ```bash
123
+ qtype publish password set # 写入 repo 配置
124
+ qtype publish build # 出栈时加密 material
125
+ ```
126
+
127
+ ## 完整规范在哪
128
+
129
+ 以上是 80% 的用法。少见场景(单卡 frontmatter 覆盖、准确的空白处理、
130
+ 分隔规则边界情形、跨文件引用)见
131
+ [`templates/zh/QTYPE.md`](../../templates/zh/QTYPE.md)。
@@ -0,0 +1,162 @@
1
+ # qtype CLI 简介
2
+
3
+ English: [cli-reference.md](../en/cli-reference.md)
4
+
5
+ 每个顶层命令的简单介绍。跑 `qtype <cmd> --help` 看完整选项。
6
+
7
+ ## 全局选项
8
+
9
+ | 选项 | 说明 |
10
+ |---|---|
11
+ | `-h, --help` | 显示帮助 |
12
+ | `-v, --version` | 显示版本 |
13
+ | `--lang <zh\|en>` | 本次调用的 UI 语言 |
14
+
15
+ 语言优先级:`--lang` > `$QTYPE_LANG` > `~/.config/qtype/config.json` 里的
16
+ `cli.lang` > 系统 locale。
17
+
18
+ ---
19
+
20
+ ## `qtype init [dir]`
21
+
22
+ 在已有目录里搭起 material 仓库脚手架。`qtype repo sync` 的别名,形态一致。
23
+
24
+ ```bash
25
+ qtype init # 当前目录
26
+ qtype init my-deck --lang en # 在 ./my-deck 下用英文模板
27
+ ```
28
+
29
+ 创建:`QTYPE.md`(撰写规范)、`AGENTS.md` / `CLAUDE.md` / `GEMINI.md`
30
+ (指向 `QTYPE.md` 的软链)、`README.md`、`TODO.md`、`index.md`、
31
+ `log.md`、含 example 的 `material/`、`.qtype/` 骨架。
32
+
33
+ 幂等 —— 跳过已有的用户内容,只有 `--force` 会覆盖 qtype 管理的规范文件。
34
+
35
+ ---
36
+
37
+ ## `qtype repo new <name>`
38
+
39
+ 新建一个 material 仓库目录。
40
+
41
+ ```bash
42
+ qtype repo new my-deck --lang zh
43
+ cd my-deck
44
+ ```
45
+
46
+ ## `qtype repo sync [dir]`
47
+
48
+ 在已有 repo 里补齐约定。与 `qtype init` 相同。
49
+
50
+ ---
51
+
52
+ ## `qtype check [dir]`
53
+
54
+ 校验 `material/*.md` 里的每张卡。报告含打字引擎无法处理字符的卡片
55
+ (返回非零码)。只读;建议在 CI 里放在 `publish build` 前面。
56
+
57
+ ```bash
58
+ qtype check
59
+ ```
60
+
61
+ ---
62
+
63
+ ## `qtype publish build [dir]`
64
+
65
+ 拼装静态站到 `dist/`。执行:
66
+
67
+ 1. 解析每个 `material/*.md`
68
+ 2. 预渲染 Mermaid 图(除非 `publish.mermaid=off`)
69
+ 3. 加密 material(如果 `publish.password.enabled=true`)
70
+ 4. 输出每份 material 的 HTML + `_data/material.json`
71
+ 5. 把预构建的 view bundle 拷到 `dist/_app/`
72
+
73
+ ```bash
74
+ qtype publish build
75
+ ```
76
+
77
+ ## `qtype publish serve [dir]`
78
+
79
+ 本地 HTTP 预览 `dist/`。默认端口 4000。
80
+
81
+ ```bash
82
+ qtype publish serve
83
+ qtype publish serve --port 8080
84
+ ```
85
+
86
+ ## `qtype publish init`
87
+
88
+ 写 `.gitignore` + GitHub Pages workflow,push 到 `main` 就触发构建 + 部署。
89
+
90
+ ## `qtype publish password set / clear / status`
91
+
92
+ 密码保护生命周期。`set` 会提示输入密码,用 Argon2id 派生 AES 密钥,
93
+ 把结果 salt + hash 写到 `.qtype/config.json`。`clear` 关闭保护。
94
+
95
+ ```bash
96
+ qtype publish password set
97
+ qtype publish password status
98
+ ```
99
+
100
+ ---
101
+
102
+ ## `qtype pack [-o file]`
103
+
104
+ 把当前 material 仓库打成 `.tar.gz`。忽略 `dist/`、`node_modules/`、
105
+ `.git/` 以及任何已存在的 tarball。
106
+
107
+ ```bash
108
+ qtype pack -o my-deck.tar.gz
109
+ ```
110
+
111
+ ---
112
+
113
+ ## `qtype content lint | validate | search`
114
+
115
+ - `lint` —— material 文件的样式级 pass
116
+ - `validate` —— schema 级 pass;`qtype check` 的补充
117
+ - `search <query>` —— 卡片全量子串搜索
118
+
119
+ ```bash
120
+ qtype content search "closure"
121
+ ```
122
+
123
+ ---
124
+
125
+ ## `qtype config get / set / unset / list`
126
+
127
+ git 风格的双层配置(user 层在 `~/.config/qtype/config.json`,repo 层
128
+ 在 `<repo>/.qtype/config.json`)。
129
+
130
+ 读优先级:repo > user > schema default。写入默认:repo-scope 键写到
131
+ repo,user-only 键写到 user,双层键优先写 repo。
132
+
133
+ ```bash
134
+ qtype config set cli.lang zh --global
135
+ qtype config set typing.theme mocha
136
+ qtype config get typing.theme --show-origin
137
+ qtype config list
138
+ qtype config unset typing.targetWpm
139
+ ```
140
+
141
+ 已知的键包括:
142
+
143
+ - `cli.lang`、`cli.color`(user-only)
144
+ - `repo.name`、`publish.password.*`(repo-only)
145
+ - `repo.lang`、`typing.theme`、`typing.targetWpm`、`typing.tabBehavior`、
146
+ `typing.hint`、`typing.showKeyboard`、`typing.showHands`、
147
+ `publish.mermaid`(双 scope)
148
+
149
+ 严格模式:未知键会被拒绝。
150
+
151
+ ---
152
+
153
+ ## `qtype plugin`
154
+
155
+ 命令骨架。运行时执行尚未实现 —— 见 [TODO.zh.md](../../TODO.zh.md)。
156
+
157
+ ---
158
+
159
+ ## 退出码
160
+
161
+ - `0` —— 成功
162
+ - `1` —— 校验 / lint / 构建失败,或任何抛出的错误
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@qnroa/qtype",
3
+ "version": "0.0.1",
4
+ "description": "Turn Markdown notes into typing practice — CLI + review + static-site publisher",
5
+ "keywords": [
6
+ "typing",
7
+ "typing-practice",
8
+ "typing-test",
9
+ "markdown",
10
+ "cli",
11
+ "static-site-generator",
12
+ "spaced-repetition",
13
+ "chinese-typing",
14
+ "pinyin",
15
+ "qrism"
16
+ ],
17
+ "license": "Apache-2.0",
18
+ "author": "Qnroa",
19
+ "homepage": "https://www.npmjs.com/package/@qnroa/qtype",
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "type": "module",
24
+ "bin": {
25
+ "qtype": "./dist/cli/index.js"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "templates",
30
+ "docs",
31
+ "CHANGELOG.md",
32
+ "CHANGELOG.zh.md",
33
+ "README.md",
34
+ "README.zh.md",
35
+ "LICENSE",
36
+ "!dist/**/*.js.map",
37
+ "!dist/**/*.d.ts.map",
38
+ "!docs/**/release.md",
39
+ "!docs/**/cli-internals.md",
40
+ "!docs/**/architecture.md",
41
+ "!docs/**/core-architecture.md",
42
+ "!docs/**/cli-architecture.md",
43
+ "!docs/**/view-architecture.md"
44
+ ],
45
+ "exports": {
46
+ "./core": "./dist/core/index.js",
47
+ "./cli": "./dist/cli/index.js"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "build": "tsc -p tsconfig.cli.json && chmod +x dist/cli/index.js",
54
+ "build:view": "vite build",
55
+ "build:all": "npm run build && npm run build:view",
56
+ "dev:view": "vite",
57
+ "test": "vitest --run",
58
+ "test:watch": "vitest",
59
+ "lint": "tsc --noEmit -p tsconfig.cli.json && tsc --noEmit -p tsconfig.view.json",
60
+ "clean": "rm -rf dist",
61
+ "prepublishOnly": "npm run clean && npm run build:all && npm test"
62
+ },
63
+ "dependencies": {
64
+ "@noble/hashes": "^2.2.0",
65
+ "commander": "^15.0.0",
66
+ "mermaid": "^11.15.0",
67
+ "pinyin-pro": "^3.29.1",
68
+ "puppeteer": "^25.4.0"
69
+ },
70
+ "devDependencies": {
71
+ "@radix-ui/react-dialog": "^1.1.23",
72
+ "@tanstack/react-router": "^1.170.29",
73
+ "@tanstack/router-plugin": "^1.168.32",
74
+ "@types/node": "^26.2.0",
75
+ "@types/react": "^18.3.11",
76
+ "@types/react-dom": "^18.3.0",
77
+ "@vitejs/plugin-react": "^4.3.2",
78
+ "react": "^18.3.1",
79
+ "react-dom": "^18.3.1",
80
+ "react-resizable-panels": "^4.12.2",
81
+ "typescript": "^5.6.2",
82
+ "vite": "^5.4.8",
83
+ "vitest": "^2.1.2"
84
+ }
85
+ }