@qnroa/qtype 0.0.1 → 0.0.3

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 (468) hide show
  1. package/CHANGELOG.md +1 -3
  2. package/CHANGELOG.zh.md +1 -2
  3. package/README.md +88 -56
  4. package/README.zh.md +82 -62
  5. package/dist/cli/bootstrap.js +4 -115
  6. package/dist/cli/commands/check/index.js +11 -10
  7. package/dist/cli/commands/config/action.js +5 -9
  8. package/dist/cli/commands/content/lint/action.js +38 -44
  9. package/dist/cli/commands/content/search/action.js +44 -34
  10. package/dist/cli/commands/content/search/i18n.js +6 -0
  11. package/dist/cli/commands/content/search/index.js +19 -1
  12. package/dist/cli/commands/content/validate/action.js +28 -27
  13. package/dist/cli/commands/index.js +1 -3
  14. package/dist/cli/commands/pack/index.js +2 -1
  15. package/dist/cli/commands/publish/build/action.js +39 -11
  16. package/dist/cli/commands/repo/new/action.js +23 -4
  17. package/dist/cli/commands/repo/new/i18n.js +2 -2
  18. package/dist/cli/commands/repo/sync/action.js +24 -4
  19. package/dist/cli/commands/repo/templates.js +2 -1
  20. package/dist/cli/utils/material.js +49 -0
  21. package/dist/core/encrypt.js +24 -1
  22. package/dist/core/index.js +1 -0
  23. package/dist/core/parser/frontmatter.js +39 -34
  24. package/dist/core/parser/parseMaterial.js +174 -24
  25. package/dist/core/romanization/index.js +152 -0
  26. package/dist/core/schemas/both.js +52 -0
  27. package/dist/core/schemas/index.js +3 -0
  28. package/dist/core/schemas/repo.js +55 -0
  29. package/dist/core/schemas/user.js +19 -0
  30. package/dist/core/typing/engine/TypingInput.js +243 -0
  31. package/dist/core/typing/engine/chars.js +30 -0
  32. package/dist/core/typing/engine/feedback.js +15 -0
  33. package/dist/core/typing/engine/index.js +5 -0
  34. package/dist/core/typing/engine/settings.js +8 -0
  35. package/dist/core/typing/engine/stats.js +45 -0
  36. package/dist/core/typing/index.js +9 -1
  37. package/dist/view/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  38. package/dist/view/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  39. package/dist/view/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  40. package/dist/view/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  41. package/dist/view/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  42. package/dist/view/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  43. package/dist/view/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  44. package/dist/view/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  45. package/dist/view/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  46. package/dist/view/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  47. package/dist/view/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  48. package/dist/view/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  49. package/dist/view/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  50. package/dist/view/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  51. package/dist/view/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  52. package/dist/view/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  53. package/dist/view/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  54. package/dist/view/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  55. package/dist/view/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  56. package/dist/view/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  57. package/dist/view/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  58. package/dist/view/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  59. package/dist/view/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  60. package/dist/view/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  61. package/dist/view/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  62. package/dist/view/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  63. package/dist/view/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  64. package/dist/view/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  65. package/dist/view/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  66. package/dist/view/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  67. package/dist/view/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  68. package/dist/view/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  69. package/dist/view/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  70. package/dist/view/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  71. package/dist/view/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  72. package/dist/view/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  73. package/dist/view/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  74. package/dist/view/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  75. package/dist/view/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  76. package/dist/view/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  77. package/dist/view/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  78. package/dist/view/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  79. package/dist/view/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  80. package/dist/view/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  81. package/dist/view/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  82. package/dist/view/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  83. package/dist/view/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  84. package/dist/view/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  85. package/dist/view/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  86. package/dist/view/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  87. package/dist/view/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  88. package/dist/view/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  89. package/dist/view/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  90. package/dist/view/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  91. package/dist/view/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  92. package/dist/view/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  93. package/dist/view/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  94. package/dist/view/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  95. package/dist/view/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  96. package/dist/view/assets/abap-BdImnpbu.js +1 -0
  97. package/dist/view/assets/actionscript-3-B3316cI-.js +1 -0
  98. package/dist/view/assets/ada-bCR0ucgS.js +1 -0
  99. package/dist/view/assets/ahk-CsyLZFj1.js +1 -0
  100. package/dist/view/assets/ahk2-8Zs4aa1G.js +1 -0
  101. package/dist/view/assets/andromeeda-C4gqWexZ.js +1 -0
  102. package/dist/view/assets/angular-html-DA-rfuFy.js +1 -0
  103. package/dist/view/assets/angular-ts-BrjP3tb8.js +1 -0
  104. package/dist/view/assets/apache-Pmp26Uib.js +1 -0
  105. package/dist/view/assets/apex-DhZFqWV2.js +1 -0
  106. package/dist/view/assets/apl-CORt7UWP.js +1 -0
  107. package/dist/view/assets/applescript-Co6uUVPk.js +1 -0
  108. package/dist/view/assets/ara-BRHolxvo.js +1 -0
  109. package/dist/view/assets/asciidoc-CSVQ5wI8.js +1 -0
  110. package/dist/view/assets/asm-D_Q5rh1f.js +1 -0
  111. package/dist/view/assets/astro-HNnZUWAn.js +1 -0
  112. package/dist/view/assets/aurora-x-D-2ljcwZ.js +1 -0
  113. package/dist/view/assets/awk-DMzUqQB5.js +1 -0
  114. package/dist/view/assets/ayu-dark-DYE7WIF3.js +1 -0
  115. package/dist/view/assets/ayu-light-BA47KaF1.js +1 -0
  116. package/dist/view/assets/ayu-mirage-32ctXXKs.js +1 -0
  117. package/dist/view/assets/ballerina-BFfxhgS-.js +1 -0
  118. package/dist/view/assets/bat-CickPsom.js +1 -0
  119. package/dist/view/assets/beancount-k_qm7-4y.js +1 -0
  120. package/dist/view/assets/berry-uYugtg8r.js +1 -0
  121. package/dist/view/assets/bibtex-CHM0blh-.js +1 -0
  122. package/dist/view/assets/bicep-Bmn6On1c.js +1 -0
  123. package/dist/view/assets/bird2-Bx8U0n9b.js +1 -0
  124. package/dist/view/assets/blade-2xfisSek.js +1 -0
  125. package/dist/view/assets/bsl-DlhNcFeZ.js +1 -0
  126. package/dist/view/assets/c-BIGW1oBm.js +1 -0
  127. package/dist/view/assets/c3-Dp5svz6Z.js +1 -0
  128. package/dist/view/assets/cadence-Bv_4Rxtq.js +1 -0
  129. package/dist/view/assets/cairo-KRGpt6FW.js +1 -0
  130. package/dist/view/assets/catppuccin-frappe-CZL1YF0i.js +1 -0
  131. package/dist/view/assets/catppuccin-latte-DH-8KZSZ.js +1 -0
  132. package/dist/view/assets/catppuccin-macchiato-B7yYVSCf.js +1 -0
  133. package/dist/view/assets/catppuccin-mocha-Ct7hS0mc.js +1 -0
  134. package/dist/view/assets/chapel-DTp_pixX.js +1 -0
  135. package/dist/view/assets/clarity-Dn5IMItf.js +1 -0
  136. package/dist/view/assets/clojure-P80f7IUj.js +1 -0
  137. package/dist/view/assets/cmake-D1j8_8rp.js +1 -0
  138. package/dist/view/assets/cobol-nBiQ_Alo.js +1 -0
  139. package/dist/view/assets/codeowners-Bp6g37R7.js +1 -0
  140. package/dist/view/assets/codeql-DsOJ9woJ.js +1 -0
  141. package/dist/view/assets/coffee-Ch7k5sss.js +1 -0
  142. package/dist/view/assets/common-lisp-Cg-RD9OK.js +1 -0
  143. package/dist/view/assets/coq-C7JzOVbR.js +1 -0
  144. package/dist/view/assets/cpp-BMRokrvK.js +1 -0
  145. package/dist/view/assets/crystal-DGywbUpC.js +1 -0
  146. package/dist/view/assets/csharp-DSvCPggb.js +1 -0
  147. package/dist/view/assets/css-CLj8gQPS.js +1 -0
  148. package/dist/view/assets/csv-fuZLfV_i.js +1 -0
  149. package/dist/view/assets/cue-D82EKSYY.js +1 -0
  150. package/dist/view/assets/cypher-COkxafJQ.js +1 -0
  151. package/dist/view/assets/d-85-TOEBH.js +1 -0
  152. package/dist/view/assets/dark-plus-C3mMm8J8.js +1 -0
  153. package/dist/view/assets/dart-bE4Kk8sk.js +1 -0
  154. package/dist/view/assets/dax-CEL-wOlO.js +1 -0
  155. package/dist/view/assets/desktop-BmXAJ9_W.js +1 -0
  156. package/dist/view/assets/diff-D97Zzqfu.js +1 -0
  157. package/dist/view/assets/docker-BcOcwvcX.js +1 -0
  158. package/dist/view/assets/dotenv-Da5cRb03.js +1 -0
  159. package/dist/view/assets/dracula-BzJJZx-M.js +1 -0
  160. package/dist/view/assets/dracula-soft-BXkSAIEj.js +1 -0
  161. package/dist/view/assets/dream-maker-BtqSS_iP.js +1 -0
  162. package/dist/view/assets/edge-FbVlp4U3.js +1 -0
  163. package/dist/view/assets/elixir-CkH2-t6x.js +1 -0
  164. package/dist/view/assets/elm-DbKCFpqz.js +1 -0
  165. package/dist/view/assets/emacs-lisp-C_m_b--Z.js +1 -0
  166. package/dist/view/assets/erb-DXfck5VN.js +1 -0
  167. package/dist/view/assets/erlang-DsQrWhSR.js +1 -0
  168. package/dist/view/assets/everforest-dark-BgDCqdQA.js +1 -0
  169. package/dist/view/assets/everforest-light-C8M2exoo.js +1 -0
  170. package/dist/view/assets/fennel-BYunw83y.js +1 -0
  171. package/dist/view/assets/fish-BvzEVeQv.js +1 -0
  172. package/dist/view/assets/fluent-C4IJs8-o.js +1 -0
  173. package/dist/view/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
  174. package/dist/view/assets/fortran-free-form-BxgE0vQu.js +1 -0
  175. package/dist/view/assets/fsharp-CXgrBDvD.js +1 -0
  176. package/dist/view/assets/gdresource-TyuKm33G.js +1 -0
  177. package/dist/view/assets/gdscript-DqcFQ5yU.js +1 -0
  178. package/dist/view/assets/gdshader-DkwncUOv.js +1 -0
  179. package/dist/view/assets/genie-D0YGMca9.js +1 -0
  180. package/dist/view/assets/gherkin-DyxjwDmM.js +1 -0
  181. package/dist/view/assets/git-commit-F4YmCXRG.js +1 -0
  182. package/dist/view/assets/git-rebase-r7XF79zn.js +1 -0
  183. package/dist/view/assets/github-dark-DHJKELXO.js +1 -0
  184. package/dist/view/assets/github-dark-default-Cuk6v7N8.js +1 -0
  185. package/dist/view/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  186. package/dist/view/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  187. package/dist/view/assets/github-light-DAi9KRSo.js +1 -0
  188. package/dist/view/assets/github-light-default-D7oLnXFd.js +1 -0
  189. package/dist/view/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  190. package/dist/view/assets/gleam-BspZqrRM.js +1 -0
  191. package/dist/view/assets/glimmer-js-ByusRIyA.js +1 -0
  192. package/dist/view/assets/glimmer-ts-BfAWNZQY.js +1 -0
  193. package/dist/view/assets/glsl-DplSGwfg.js +1 -0
  194. package/dist/view/assets/gn-n2N0HUVH.js +1 -0
  195. package/dist/view/assets/gnuplot-DdkO51Og.js +1 -0
  196. package/dist/view/assets/go-C27-OAKa.js +1 -0
  197. package/dist/view/assets/graphql-ChdNCCLP.js +1 -0
  198. package/dist/view/assets/groovy-gcz8RCvz.js +1 -0
  199. package/dist/view/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  200. package/dist/view/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  201. package/dist/view/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  202. package/dist/view/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  203. package/dist/view/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  204. package/dist/view/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  205. package/dist/view/assets/hack-BWmVpMyf.js +1 -0
  206. package/dist/view/assets/haml-D5jkg6IW.js +1 -0
  207. package/dist/view/assets/handlebars-BpdQsYii.js +1 -0
  208. package/dist/view/assets/haskell-Df6bDoY_.js +1 -0
  209. package/dist/view/assets/haxe-CfZj7gIn.js +1 -0
  210. package/dist/view/assets/hcl-BWvSN4gD.js +1 -0
  211. package/dist/view/assets/hjson-D5-asLiD.js +1 -0
  212. package/dist/view/assets/hlsl-D3lLCCz7.js +1 -0
  213. package/dist/view/assets/horizon-BUw7H-hv.js +1 -0
  214. package/dist/view/assets/horizon-bright-CUuTKBJd.js +1 -0
  215. package/dist/view/assets/houston-DnULxvSX.js +1 -0
  216. package/dist/view/assets/html-derivative-DlHx6ybY.js +1 -0
  217. package/dist/view/assets/html-pp8916En.js +1 -0
  218. package/dist/view/assets/http-jrhK8wxY.js +1 -0
  219. package/dist/view/assets/hurl-irOxFIW8.js +1 -0
  220. package/dist/view/assets/hxml-2-FPmUDs.js +1 -0
  221. package/dist/view/assets/hy-DFXneXwc.js +1 -0
  222. package/dist/view/assets/imba-DGztddWO.js +1 -0
  223. package/dist/view/assets/index-BLryk3W4.css +1 -0
  224. package/dist/view/assets/index-ByMJp0a5.js +3 -0
  225. package/dist/view/assets/index-CRh4USfC.js +189 -0
  226. package/dist/view/assets/index-JNx7Ohoj.js +153 -0
  227. package/dist/view/assets/ini-BEwlwnbL.js +1 -0
  228. package/dist/view/assets/java-CylS5w8V.js +1 -0
  229. package/dist/view/assets/javascript-wDzz0qaB.js +1 -0
  230. package/dist/view/assets/jinja-f2NsQr07.js +1 -0
  231. package/dist/view/assets/jison-wvAkD_A8.js +1 -0
  232. package/dist/view/assets/json-Cp-IABpG.js +1 -0
  233. package/dist/view/assets/json5-C9tS-k6U.js +1 -0
  234. package/dist/view/assets/jsonc-Des-eS-w.js +1 -0
  235. package/dist/view/assets/jsonl-DcaNXYhu.js +1 -0
  236. package/dist/view/assets/jsonnet-DFQXde-d.js +1 -0
  237. package/dist/view/assets/jssm-C2t-YnRu.js +1 -0
  238. package/dist/view/assets/jsx-g9-lgVsj.js +1 -0
  239. package/dist/view/assets/julia-5Bft2YPA.js +1 -0
  240. package/dist/view/assets/just-Cwhn7H3k.js +1 -0
  241. package/dist/view/assets/kanagawa-dragon-BuwD2xS4.js +1 -0
  242. package/dist/view/assets/kanagawa-lotus-C3DzagqV.js +1 -0
  243. package/dist/view/assets/kanagawa-wave-DFGoQZhC.js +1 -0
  244. package/dist/view/assets/katex-BYZTj3zW.css +1 -0
  245. package/dist/view/assets/katex-C5jXJg4s.js +257 -0
  246. package/dist/view/assets/kdl-DV7GczEv.js +1 -0
  247. package/dist/view/assets/kotlin-BdnUsdx6.js +1 -0
  248. package/dist/view/assets/kusto-wEQ09or8.js +1 -0
  249. package/dist/view/assets/laserwave-DUszq2jm.js +1 -0
  250. package/dist/view/assets/latex-D5pSuvFb.js +1 -0
  251. package/dist/view/assets/lean-BZvkOJ9d.js +1 -0
  252. package/dist/view/assets/less-B1dDrJ26.js +1 -0
  253. package/dist/view/assets/light-plus-B7mTdjB0.js +1 -0
  254. package/dist/view/assets/liquid-C0sCDyMI.js +1 -0
  255. package/dist/view/assets/llvm-BZoOZj88.js +1 -0
  256. package/dist/view/assets/log-2UxHyX5q.js +1 -0
  257. package/dist/view/assets/logo-BtOb2qkB.js +1 -0
  258. package/dist/view/assets/lua-BaeVxFsk.js +1 -0
  259. package/dist/view/assets/luau-BnpPk5vE.js +1 -0
  260. package/dist/view/assets/make-CHLpvVh8.js +1 -0
  261. package/dist/view/assets/markdown-Cvjx9yec.js +1 -0
  262. package/dist/view/assets/marko-DjSrsDqO.js +1 -0
  263. package/dist/view/assets/material-theme-D5KoaKCx.js +1 -0
  264. package/dist/view/assets/material-theme-darker-BfHTSMKl.js +1 -0
  265. package/dist/view/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  266. package/dist/view/assets/material-theme-ocean-CyktbL80.js +1 -0
  267. package/dist/view/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  268. package/dist/view/assets/matlab-D7o27uSR.js +1 -0
  269. package/dist/view/assets/mdc-D1_yUvq7.js +1 -0
  270. package/dist/view/assets/mdx-Cmh6b_Ma.js +1 -0
  271. package/dist/view/assets/mermaid-CQcHuHx7.js +1 -0
  272. package/dist/view/assets/min-dark-CafNBF8u.js +1 -0
  273. package/dist/view/assets/min-light-CTRr51gU.js +1 -0
  274. package/dist/view/assets/mipsasm-CKIfxQSi.js +1 -0
  275. package/dist/view/assets/mojo-DJz3ZmWd.js +1 -0
  276. package/dist/view/assets/monokai-BRVnQi9A.js +1 -0
  277. package/dist/view/assets/moonbit-CHtswR0a.js +1 -0
  278. package/dist/view/assets/move-el3G9tDJ.js +1 -0
  279. package/dist/view/assets/narrat-DRg8JJMk.js +1 -0
  280. package/dist/view/assets/nextflow-C-mBbutL.js +1 -0
  281. package/dist/view/assets/nextflow-groovy-vE_lwT2v.js +1 -0
  282. package/dist/view/assets/nginx-BpAMiNFr.js +1 -0
  283. package/dist/view/assets/night-owl-C39BiMTA.js +1 -0
  284. package/dist/view/assets/night-owl-light-CMTm3GFP.js +1 -0
  285. package/dist/view/assets/nim-BIad80T-.js +1 -0
  286. package/dist/view/assets/nix-CwoSXNpI.js +1 -0
  287. package/dist/view/assets/nord-Ddv68eIx.js +1 -0
  288. package/dist/view/assets/nsis-BlV79W_Q.js +1 -0
  289. package/dist/view/assets/nushell-D3jzshHO.js +1 -0
  290. package/dist/view/assets/objective-c-DXmwc3jG.js +1 -0
  291. package/dist/view/assets/objective-cpp-CLxacb5B.js +1 -0
  292. package/dist/view/assets/ocaml-C0hk2d4L.js +1 -0
  293. package/dist/view/assets/odin-BBf5iR-q.js +1 -0
  294. package/dist/view/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  295. package/dist/view/assets/one-light-C3Wv6jpd.js +1 -0
  296. package/dist/view/assets/openscad-C4EeE6gA.js +1 -0
  297. package/dist/view/assets/org-DM6o9KBp.js +1 -0
  298. package/dist/view/assets/pascal-D93ZcfNL.js +1 -0
  299. package/dist/view/assets/perl-B9cMNwum.js +1 -0
  300. package/dist/view/assets/php-Csjmro_R.js +1 -0
  301. package/dist/view/assets/pkl-u5AG7uiY.js +1 -0
  302. package/dist/view/assets/plastic-3e1v2bzS.js +1 -0
  303. package/dist/view/assets/plsql-ChMvpjG-.js +1 -0
  304. package/dist/view/assets/po-BTJTHyun.js +1 -0
  305. package/dist/view/assets/poimandres-CS3Unz2-.js +1 -0
  306. package/dist/view/assets/polar-C0HS_06l.js +1 -0
  307. package/dist/view/assets/postcss-CXtECtnM.js +1 -0
  308. package/dist/view/assets/powerquery-CEu0bR-o.js +1 -0
  309. package/dist/view/assets/powershell-BmBUJMz7.js +1 -0
  310. package/dist/view/assets/prisma-Vru482bI.js +1 -0
  311. package/dist/view/assets/prolog-CbFg5uaA.js +1 -0
  312. package/dist/view/assets/proto-C7zT0LnQ.js +1 -0
  313. package/dist/view/assets/pug-DKIMFp6K.js +1 -0
  314. package/dist/view/assets/puppet-BMWR74SV.js +1 -0
  315. package/dist/view/assets/purescript-CklMAg4u.js +1 -0
  316. package/dist/view/assets/python-B6aJPvgy.js +1 -0
  317. package/dist/view/assets/qml-3beO22l8.js +1 -0
  318. package/dist/view/assets/qmldir-C8lEn-DE.js +1 -0
  319. package/dist/view/assets/qss-IeuSbFQv.js +1 -0
  320. package/dist/view/assets/r-Cf5RLm7j.js +1 -0
  321. package/dist/view/assets/racket-BqYA7rlc.js +1 -0
  322. package/dist/view/assets/raku-DXvB9xmW.js +1 -0
  323. package/dist/view/assets/razor-BjBPvh-w.js +1 -0
  324. package/dist/view/assets/rbs-CpoqiR4B.js +1 -0
  325. package/dist/view/assets/red-hvxz__6c.js +1 -0
  326. package/dist/view/assets/reg-C-SQnVFl.js +1 -0
  327. package/dist/view/assets/regexp-CDVJQ6XC.js +1 -0
  328. package/dist/view/assets/rel-C3B-1QV4.js +1 -0
  329. package/dist/view/assets/riscv-BM1_JUlF.js +1 -0
  330. package/dist/view/assets/ron-D8l8udqQ.js +1 -0
  331. package/dist/view/assets/rose-pine-5qJOZa0Y.js +1 -0
  332. package/dist/view/assets/rose-pine-dawn-zx0QlTCp.js +1 -0
  333. package/dist/view/assets/rose-pine-moon-C9pEdX9L.js +1 -0
  334. package/dist/view/assets/rosmsg-BJDFO7_C.js +1 -0
  335. package/dist/view/assets/rst-bs7f0vWN.js +1 -0
  336. package/dist/view/assets/ruby-C0TQ7zu5.js +1 -0
  337. package/dist/view/assets/rust-B1yitclQ.js +1 -0
  338. package/dist/view/assets/sas-DEy46yEz.js +1 -0
  339. package/dist/view/assets/sass-Cj5Yp3dK.js +1 -0
  340. package/dist/view/assets/scala-CqE71os6.js +1 -0
  341. package/dist/view/assets/scheme-C98Dy4si.js +1 -0
  342. package/dist/view/assets/scss-D5BDwBP9.js +1 -0
  343. package/dist/view/assets/sdbl-DVxCFoDh.js +1 -0
  344. package/dist/view/assets/shaderlab-Dg9Lc6iA.js +1 -0
  345. package/dist/view/assets/shellscript-Yzrsuije.js +1 -0
  346. package/dist/view/assets/shellsession-BADoaaVG.js +1 -0
  347. package/dist/view/assets/slack-dark-BthQWCQV.js +1 -0
  348. package/dist/view/assets/slack-ochin-DqwNpetd.js +1 -0
  349. package/dist/view/assets/smalltalk-BOQMe2GC.js +1 -0
  350. package/dist/view/assets/smithy-cds9vsN8.js +1 -0
  351. package/dist/view/assets/snazzy-light-Bw305WKR.js +1 -0
  352. package/dist/view/assets/solarized-dark-CpvCGNkr.js +1 -0
  353. package/dist/view/assets/solarized-light-Dlz6yCKv.js +1 -0
  354. package/dist/view/assets/solidity-DijEV5ha.js +1 -0
  355. package/dist/view/assets/soy-8wufbnw4.js +1 -0
  356. package/dist/view/assets/sparql-rVzFXLq3.js +1 -0
  357. package/dist/view/assets/splunk-BtCnVYZw.js +1 -0
  358. package/dist/view/assets/sql-CRqJ_cUM.js +1 -0
  359. package/dist/view/assets/ssh-config-_ykCGR6B.js +1 -0
  360. package/dist/view/assets/stata-DI20mbqo.js +1 -0
  361. package/dist/view/assets/stylus-BEDo0Tqx.js +1 -0
  362. package/dist/view/assets/surrealql-Cjom0U5J.js +1 -0
  363. package/dist/view/assets/svelte-Cy7k_4gC.js +1 -0
  364. package/dist/view/assets/swift-C2oV4EkX.js +1 -0
  365. package/dist/view/assets/synthwave-84-CbfX1IO0.js +1 -0
  366. package/dist/view/assets/system-verilog-0hqHdDBg.js +1 -0
  367. package/dist/view/assets/systemd-4A_iFExJ.js +1 -0
  368. package/dist/view/assets/talonscript-CkByrt1z.js +1 -0
  369. package/dist/view/assets/tasl-QIJgUcNo.js +1 -0
  370. package/dist/view/assets/tcl-dwOrl1Do.js +1 -0
  371. package/dist/view/assets/templ-DhtptRzy.js +1 -0
  372. package/dist/view/assets/terraform-BETggiCN.js +1 -0
  373. package/dist/view/assets/tex-D96PA37w.js +1 -0
  374. package/dist/view/assets/tokyo-night-hegEt444.js +1 -0
  375. package/dist/view/assets/toml-vGWfd6FD.js +1 -0
  376. package/dist/view/assets/ts-tags-D351s5mN.js +1 -0
  377. package/dist/view/assets/tsv-B_m7g4N7.js +1 -0
  378. package/dist/view/assets/tsx-COt5Ahok.js +1 -0
  379. package/dist/view/assets/turtle-BsS91CYL.js +1 -0
  380. package/dist/view/assets/twig-27uCiNez.js +1 -0
  381. package/dist/view/assets/typescript-BPQ3VLAy.js +1 -0
  382. package/dist/view/assets/typespec-CAFt9gP4.js +1 -0
  383. package/dist/view/assets/typst-BUadGCkm.js +1 -0
  384. package/dist/view/assets/v-BGw2Nkan.js +1 -0
  385. package/dist/view/assets/vala-CsfeWuGM.js +1 -0
  386. package/dist/view/assets/vb-Cu-pLBUe.js +1 -0
  387. package/dist/view/assets/verilog-nZwndyjY.js +1 -0
  388. package/dist/view/assets/vesper-DRje8inN.js +1 -0
  389. package/dist/view/assets/vhdl-CeAyd5Ju.js +1 -0
  390. package/dist/view/assets/viml-CJc9bBzg.js +1 -0
  391. package/dist/view/assets/vitesse-black-Bkuqu6BP.js +1 -0
  392. package/dist/view/assets/vitesse-dark-D0r3Knsf.js +1 -0
  393. package/dist/view/assets/vitesse-light-CVO1_9PV.js +1 -0
  394. package/dist/view/assets/vue-BqiEGhQt.js +1 -0
  395. package/dist/view/assets/vue-html-AaS7Mt5G.js +1 -0
  396. package/dist/view/assets/vue-vine-BoDAl6tE.js +1 -0
  397. package/dist/view/assets/vyper-CDx5xZoG.js +1 -0
  398. package/dist/view/assets/wasm-CG6Dc4jp.js +1 -0
  399. package/dist/view/assets/wasm-MzD3tlZU.js +1 -0
  400. package/dist/view/assets/wenyan-BV7otONQ.js +1 -0
  401. package/dist/view/assets/wgsl-Dx-B1_4e.js +1 -0
  402. package/dist/view/assets/wikitext-BhOHFoWU.js +1 -0
  403. package/dist/view/assets/wit-5i3qLPDT.js +1 -0
  404. package/dist/view/assets/wolfram-lXgVvXCa.js +1 -0
  405. package/dist/view/assets/xml-sdJ4AIDG.js +1 -0
  406. package/dist/view/assets/xsl-CtQFsRM5.js +1 -0
  407. package/dist/view/assets/yaml-Buea-lGh.js +1 -0
  408. package/dist/view/assets/zenscript-DVFEvuxE.js +1 -0
  409. package/dist/view/assets/zig-VOosw3JB.js +1 -0
  410. package/dist/view/index.html +10 -2
  411. package/docs/README.md +21 -15
  412. package/docs/README.zh.md +15 -9
  413. package/docs/en/authoring.md +85 -80
  414. package/docs/en/cli-reference.md +110 -72
  415. package/docs/en/deployment.md +183 -0
  416. package/docs/en/getting-started.md +112 -0
  417. package/docs/en/material-types.md +241 -0
  418. package/docs/en/settings.md +133 -0
  419. package/docs/en/shortcuts.md +89 -0
  420. package/docs/en/typing-rules.md +208 -0
  421. package/docs/zh/authoring.md +74 -69
  422. package/docs/zh/cli-reference.md +92 -58
  423. package/docs/zh/deployment.md +179 -0
  424. package/docs/zh/getting-started.md +104 -0
  425. package/docs/zh/material-types.md +769 -0
  426. package/docs/zh/settings.md +120 -0
  427. package/docs/zh/shortcuts.md +83 -0
  428. package/docs/zh/typing-rules.md +191 -0
  429. package/package.json +13 -11
  430. package/templates/en/QTYPE.md +155 -495
  431. package/templates/en/README.md +11 -11
  432. package/templates/en/TODO.md +1 -1
  433. package/templates/en/material/article.md +20 -0
  434. package/templates/en/material/assets/article/sunrise.svg +12 -0
  435. package/templates/en/material/assets/code/tree.svg +19 -0
  436. package/templates/en/material/assets/qa/login-flow.svg +17 -0
  437. package/templates/en/material/assets/sentence/pangram.svg +6 -0
  438. package/templates/en/material/assets/snippet/moon.svg +8 -0
  439. package/templates/en/material/assets/word/apple.svg +5 -0
  440. package/templates/en/material/code.md +55 -0
  441. package/templates/en/material/qa.md +33 -0
  442. package/templates/en/material/sentence.md +18 -0
  443. package/templates/en/material/snippet.md +17 -0
  444. package/templates/en/material/word.md +20 -0
  445. package/templates/zh/QTYPE.md +191 -473
  446. package/templates/zh/README.md +6 -6
  447. package/templates/zh/index.md +1 -1
  448. package/templates/zh/material/article.md +18 -0
  449. package/templates/zh/material/assets/article/sunrise.svg +12 -0
  450. package/templates/zh/material/assets/code/tree.svg +19 -0
  451. package/templates/zh/material/assets/qa/login-flow.svg +17 -0
  452. package/templates/zh/material/assets/sentence/pangram.svg +6 -0
  453. package/templates/zh/material/assets/snippet/moon.svg +8 -0
  454. package/templates/zh/material/assets/word/apple.svg +5 -0
  455. package/templates/zh/material/code.md +55 -0
  456. package/templates/zh/material/qa.md +33 -0
  457. package/templates/zh/material/sentence.md +19 -0
  458. package/templates/zh/material/snippet.md +20 -0
  459. package/templates/zh/material/word.md +20 -0
  460. package/dist/cli/commands/check/action.js +0 -56
  461. package/dist/cli/commands/check/i18n.js +0 -26
  462. package/dist/cli/commands/plugin/i18n.js +0 -28
  463. package/dist/cli/commands/plugin/index.js +0 -41
  464. package/dist/core/typing/engine.js +0 -112
  465. package/dist/view/assets/index-DBABH3dG.js +0 -111
  466. package/dist/view/assets/index-RTLZ-zOC.css +0 -1
  467. package/templates/en/material/example.md +0 -47
  468. package/templates/zh/material/example.md +0 -47
@@ -15,604 +15,322 @@ qtype 是一个以 Markdown 为源、以 OS 键盘(含中文 IME)为输入
15
15
  - 用户负责**选主题**或**扔材料**。你负责**读、提炼、切成卡片、归档、维护**。
16
16
  - 你不是问答机器人,你是**打字练习卡片库的作者**。每张卡片都要真的可以被用户敲出来。
17
17
  - `raw/` 是用户扔进来的原始材料(可选目录),**不可改内容**。
18
- - `material/` 下的每个 `.md` 文件是一个卡组(deck),**完全由你维护**(用户手写的除外)。
18
+ - `material/` 下的每个 `.md` 文件是一个素材(material),**完全由你维护**(用户手写的除外)。
19
19
  - 卡片不是随便的问答对,是**能被真人打字的字符串**——所有字符必须在 OS 键盘或中文 IME 下打得出来。
20
20
 
21
21
  ### 术语
22
22
 
23
23
  | 术语 | 定义 |
24
24
  |---|---|
25
- | 仓库 | 一个独立的 qtype 目录(例如 `my-typing-deck/`) |
26
- | 卡组 (deck) | `material/` 下的一个 `.md` 文件,含若干张卡片 |
27
- | 卡片 (card) | 一个 `## Q:` + `## A:` 单元,前面有一段 frontmatter |
28
- | 标签 (tag) | 卡片或卡组的分类标记,用于筛选和目录归组 |
29
- | 单词卡 | `type: word`,练拼写和词形,含 `phonetic` `gloss` |
30
- | 句子卡 | `type: sentence`,练成句连打,含 `translation` |
31
- | 普通卡 | `type: normal`(默认),Q 是提示、A 是答案,形式最自由 |
32
- | raw 材料 | `raw/` 下的原始文本(可选),用于 ingest 生成卡片 |
33
- | log | `log.md`,只追加的时间线日志 |
34
- | 复习进度 | 用户在 Web UI 中练习后产生的本地进度数据(Agent 不管) |
25
+ | 仓库 | 一个独立的 qtype 目录 |
26
+ | 素材 (material) | `material/` 下的一个 `.md` 文件,含若干张卡片 |
27
+ | 卡片 (card) | 一个 `#` H1 及其下方内容 |
28
+ | 标签 (tag) | 素材的分类标记,只在 material-level 声明 |
29
+ | type | 素材的形态类型,决定卡片内部结构:`word` / `sentence` / `article` / `snippet` / `qa` / `code` |
35
30
 
36
31
  ### 目录布局
37
32
 
38
33
  ```
39
34
  <仓库根>/
40
- ├── QTYPE.md # 本文件(规则与操作;语言由 qtype 在创建时选定)
35
+ ├── QTYPE.md # 本文件(规则与操作)
41
36
  ├── AGENTS.md # 软链 → QTYPE.md
42
37
  ├── CLAUDE.md # 软链 → QTYPE.md
43
38
  ├── GEMINI.md # 软链 → QTYPE.md
44
39
  ├── README.md # 仓库介绍(由人维护)
45
- ├── TODO.md # 待补清单(由 todo 命令维护)
46
- ├── index.md # 全部卡组的目录,按标签分组
40
+ ├── TODO.md # 待补清单
41
+ ├── index.md # 全部素材的目录,按标签分组
47
42
  ├── log.md # 时间线日志,只追加
48
- ├── qtype.config.json # 用户可调设置(主题、目标 WPM、hint 模式等)
49
- ├── material/ # 你写的卡组
43
+ ├── qtype.config.json # 用户可调设置
44
+ ├── material/ # 你写的素材
50
45
  │ ├── .gitkeep
51
- │ ├── <slug>.md # 一个卡组一个文件
52
- │ └── assets/ # 卡组引用的图片和其他二进制
53
- │ └── <deck-slug>/
54
- │ └── xxx.png
46
+ │ ├── <slug>.md # 一个素材一个文件
47
+ │ └── assets/ # 素材引用的图片
48
+ │ └── <material-slug>/
55
49
  └── raw/ # (可选)用户扔进来的原始材料
56
50
  ├── .gitkeep
57
51
  ├── YYYY-MM-DD-<slug>.md
58
52
  └── assets/
59
- └── <raw-slug>/
60
53
  ```
61
54
 
62
- 规则:
63
-
64
- - `material/` 下**平铺**所有卡组文件,**只允许**一个子目录 `assets/`(存卡组引用的图片和其他二进制)。
65
- - `raw/` 下**平铺**所有源文件,**只允许**一个子目录 `assets/`(存 raw 引用的图片和其他二进制)。
66
- - `material/assets/<deck-slug>/` 和 `raw/assets/<raw-slug>/`:按所属 md 文件的 slug 分文件夹,避免全局命名冲突。
67
- - **首次操作时兜底检查骨架**:仓库的标准初始化由用户完成。Agent 进入仓库时,若 `material/` / `index.md` / `log.md` 有缺失,按规范补建。`material/` 和 `raw/` 新建时放入 `.gitkeep`。
68
- - `raw/` 是可选目录,用户不扔材料时可不建。
69
- - 只建本文件规定的目录和文件,**不建**任何规则外的东西。
70
-
71
55
  ---
72
56
 
73
57
  ## 格式
74
58
 
75
- ### 命名
76
-
77
- **卡组文件名**
78
-
79
- - 路径:`material/<slug>.md`
80
- - `<slug>`:主题的 kebab-case,小写,英文字母和短横线,最长 60 字符。中文主题用英译或拼音。
81
- - 同名冲突:末尾追加 `-2` / `-3` 等数字后缀。
82
- - 例:`gre-vocab-list-3.md`、`react-hooks-quiz.md`、`toefl-idioms.md`。
83
-
84
- **raw 文件名**
85
-
86
- - 路径:`raw/YYYY-MM-DD-<slug>.md`
87
- - `YYYY-MM-DD`:材料被收入本仓库的日期。
88
- - `<slug>`:材料标题的 kebab-case。
89
- - 没有明确标题的粘贴文本用 `YYYY-MM-DD-note-<N>.md`。
90
-
91
- **assets 命名**
92
-
93
- - `material/assets/<deck-slug>/` 和 `raw/assets/<raw-slug>/`:按所属 md 文件的 slug 分组,slug 一致时资产同一目录。
59
+ ### Material 顶部 frontmatter
94
60
 
95
- ### 链接
96
-
97
- **只用 Markdown link,不用 Wikilink**。
98
-
99
- | 场景 | 路径写法 | 例子 |
100
- |---|---|---|
101
- | 卡组文件引用另一个卡组 | `./<slug>.md` | `[GRE 高频](./gre-vocab-list-3.md)` |
102
- | 卡组引用 raw 文件 | `../raw/<文件名>.md` | `[原文](../raw/2026-08-14-mdn-closures.md)` |
103
- | 卡组引用 material/assets 下的图片 | `./assets/<deck-slug>/<文件>` | `![图示](./assets/react-hooks-quiz/lifecycle.png)` |
104
- | 卡组引用 raw/assets 下的图片 | `../raw/assets/<raw-slug>/<文件>` | `![原图](../raw/assets/2026-08-14-mdn-closures/scope.png)` |
105
- | index.md / log.md 引用卡组 | 从仓库根起 | `material/gre-vocab-list-3.md` |
106
-
107
- 规则:
108
-
109
- - **绝不**用 `[[wikilink]]` 语法。
110
- - **绝不**用绝对路径(不以 `./` 或 `../` 开头的都不行)。
111
- - 链接目标必须是实际存在的文件。
112
-
113
- ### Deck 文件头(deck-level frontmatter)
114
-
115
- 每个 deck 文件必须以一段 YAML frontmatter 开头,描述整个卡组:
61
+ 每个 material 文件必须以一段 YAML frontmatter 开头,**决定整个素材所有卡片的形态**:
116
62
 
117
63
  ```yaml
118
64
  ---
119
- title: <卡组标题>
120
- language: <目标语言 ISO 代码,如 en / zh / ja>
121
- tags: [<标签 1>, <标签 2>]
65
+ title: <素材标题>
66
+ type: word | sentence | article | snippet | qa | code
67
+ tags: [<t1>, <t2>]
122
68
  created: YYYY-MM-DD
123
69
  updated: YYYY-MM-DD
124
70
  ---
125
71
  ```
126
72
 
127
- 字段说明:
128
-
129
- - `title`:卡组标题。给人看的,可带中文。
130
- - `language`:卡组答案文本的主要语言(决定 IME 提示、输入法预期)。常用值:`en` / `zh` / `ja` / `mixed`。
131
- - `tags`:数组或空格分隔字符串。至少一个,用于 `index.md` 的分组。
132
- - `created` / `updated`:日期。每次卡组内容变化时 bump `updated`。
73
+ **规则**:
133
74
 
134
- deck 文件头之后**紧接**第一张卡片的 frontmatter(用 `---` 分隔),不写 deck 层的正文说明——注释信息放在 README 或 index。
75
+ - `title`:素材标题,人看的
76
+ - `type`:**必填**,决定所有卡片的解析规则和渲染样式
77
+ - `tags`:数组或空格分隔,至少一个
78
+ - `created` / `updated`:日期。内容变化时 bump `updated`
79
+ - **一个 material 只有一个 type**,一个文件的所有卡片形态一致
135
80
 
136
- ### 卡片 frontmatter
81
+ **没有 card-level frontmatter**。所有卡片信息都由 markdown 结构表达。
137
82
 
138
- 每张卡片以自己的一段 frontmatter 开头,字段:
83
+ ### Card 结构
139
84
 
140
- | 字段 | | 适用 | 说明 |
141
- |---|---|---|---|
142
- | `type` | `normal` \| `word` \| `sentence` | 全部 | 默认 `normal`。 |
143
- | `tags` | 数组或空格分隔字符串 | 可选 | 卡片级标签,可与 deck 标签重叠。 |
144
- | `difficulty` | 1..5 整数 | 可选 | 1=极易,5=极难。默认 3。 |
145
- | `hint` | `none` \| `ghost` | 可选 | 覆盖全局 hint 模式。不写=跟随全局。 |
146
- | `phonetic` | IPA 字符串,`/…/` 或 `[…]` | 单词卡 | 例 `/əˈbæn.dən/`。 |
147
- | `gloss` | 简中释义 | 单词卡 | 例 `抛弃, 放弃`。 |
148
- | `translation` | 目标句子的译文 | 句子卡 | 表意即可,不必逐字对齐。 |
85
+ **H1(`#`)分卡**:每一个 H1 起一张新卡片。下一个 H1 = 下一张卡。**不用 `---` 分隔**。
149
86
 
150
- 规则:
87
+ **按 type 分六种结构**:
151
88
 
152
- - 单词卡**必须**写 `phonetic` 和 `gloss`。
153
- - 句子卡**必须**写 `translation`。
154
- - 普通卡可以不写任何可选字段。
155
- - 未列在上表的字段一律不允许,避免格式漂移。
89
+ #### type: word
156
90
 
157
- ### 卡片结构
158
-
159
- 一张卡片包含 frontmatter、`## Q:` 段、`## A:` 段:
91
+ 单词卡。H1 = 打字目标;H2/H3/H4 是可选注解,位置固定。
160
92
 
161
93
  ```md
162
- ---
163
- type: word
164
- phonetic: /əˈbæn.dən/
165
- gloss: 抛弃, 放弃
166
- tags: [gre]
167
- difficulty: 2
168
- ---
169
- ## Q: abandon
170
- ## A: abandon
171
- ```
172
-
173
- 规则:
174
-
175
- - `## Q:` 段:提示信息。用户练习时会看到。
176
- - `## A:` 段:**用户实际要敲的文本**。
177
- - 卡片之间用一行空行 + `---` + 一行空行分隔(即紧接下一张卡片的 frontmatter 起始行)。
178
- - deck 文件头 frontmatter 关闭的 `---` 之后紧跟第一张卡片的 frontmatter;不允许在两者之间夹正文。
179
-
180
- **答案文本约束(`## A:` 的内容)**:
181
-
182
- - 只允许 OS 键盘(含中文 IME)能打出的字符。禁用 emoji、零宽字符、大多数罕见 Unicode。
183
- - 全角中文标点会被工具自动规范化(弯引号 → 直引号、破折号 → 双连字符等),你按自然汉语标点写即可。
184
- - 长度**建议**不超过 200 字符——过长影响体验,宁可拆成多张卡片。
185
- - 允许包含空格、换行(Enter)、Tab。换行在答案文本中用真实换行(Markdown 里空一行会破坏解析,用软换行或不换)。
186
-
187
- ### 卡片示例
94
+ # abandon
95
+ ## /əˈbæn.dən/
96
+ ### 抛弃, 放弃
97
+ #### ![](./assets/vocab/abandon.jpg)
188
98
 
189
- **单词卡(word)**
99
+ # ephemeral
100
+ ## /əˈfem(ə)rəl/
101
+ ### 短暂的
190
102
 
191
- ```md
192
- ---
193
- type: word
194
- phonetic: /əˈbæn.dən/
195
- gloss: 抛弃, 放弃
196
- tags: [gre]
197
- difficulty: 2
198
- ---
199
- ## Q: abandon
200
- ## A: abandon
103
+ # barebones
201
104
  ```
202
105
 
203
- **句子卡(sentence)**
106
+ | 层级 | 内容 | 可选 |
107
+ |---|---|---|
108
+ | **H1** | 打字目标(要敲的词) | 必填 |
109
+ | **H2** | 音标 / 拼音 | 可选 |
110
+ | **H3** | 释义 / 简译 | 可选 |
111
+ | **H4** | 图片,用 `![](url)` markdown 语法 | 可选 |
204
112
 
205
- ```md
206
- ---
207
- type: sentence
208
- translation: 熟能生巧。
209
- tags: [idiom]
210
- difficulty: 3
211
- ---
212
- ## Q: Practice makes perfect.
213
- ## A: Practice makes perfect.
214
- ```
113
+ #### type: sentence
215
114
 
216
- **普通卡(normal)**
115
+ 句子卡。**同 word 结构**,H1 = 打字目标(完整句子)。
217
116
 
218
117
  ```md
219
- ---
220
- type: normal
221
- tags: [js, closures]
222
- difficulty: 4
223
- ---
224
- ## Q: 闭包在 JavaScript 中是什么?
225
- ## A: 函数与其词法作用域的组合,允许函数访问定义时的作用域中的变量。
118
+ # Practice makes perfect.
119
+ ### 熟能生巧。
120
+
121
+ # 举头望明月,低头思故乡。
122
+ ### 抬头看月亮,低头想故乡。
226
123
  ```
227
124
 
228
- 普通卡的 A 段是**用户要敲**的答案文本;Q 段是提示。可以让 A 是一段代码片段、一句话、一个短语——但必须满足答案文本约束。
125
+ | 层级 | 内容 | 可选 |
126
+ |---|---|---|
127
+ | **H1** | 打字目标(要敲的句子) | 必填 |
128
+ | **H2** | 音标 / 拼音 | 可选(句子级少用) |
129
+ | **H3** | 翻译 | 可选 |
130
+ | **H4** | 图片 | 可选 |
229
131
 
230
- ### `index.md` 格式
132
+ #### type: article
231
133
 
232
- `index.md` 在仓库根,按标签分组。每次 ingest / update / quiz-gen 后**必须**同步更新。
134
+ 文章卡。**H1 = 卡片标题(不打),H1 之下的正文是打字目标**。
233
135
 
234
136
  ```md
235
- ---
236
- updated: YYYY-MM-DD
237
- ---
238
-
239
- # 索引
240
-
241
- ## <标签 1>
137
+ # 早起习惯
242
138
 
243
- | 卡组 | 卡片数 | 语言 | 摘要 | 更新 |
244
- |---|---|---|---|---|
245
- | [标题 1](material/<文件 1>.md) | 32 | en | 一行摘要 | YYYY-MM-DD |
246
- | [标题 2](material/<文件 2>.md) | 25 | zh | 一行摘要 | YYYY-MM-DD |
139
+ Wake up early. Drink a glass of water. Start typing for ten minutes.
140
+ Consistency beats intensity — that's how habits compound over time.
247
141
 
248
- ## <标签 2>
142
+ # 200 字自我介绍
249
143
 
250
- | 卡组 | 卡片数 | 语言 | 摘要 | 更新 |
251
- |---|---|---|---|---|
252
- | [标题 3](material/<文件 3>.md) | 40 | mixed | 一行摘要 | YYYY-MM-DD |
144
+ Hello, my name is Alice. I'm a software engineer based in Shanghai.
253
145
  ```
254
146
 
255
- 规则:
147
+ | 层级 | 内容 |
148
+ |---|---|
149
+ | **H1** | 卡片标题 / 章节名(不打) |
150
+ | **H1 之下** | 所有普通段落 = 打字目标 |
256
151
 
257
- - 一个标签一个 `##` 标题。**同一卡组可出现在多个标签**(tags 有多个时全部列出)。
258
- - 每个标签下**只有一个 markdown 表格**,不加别的内容。
259
- - 链接路径从仓库根起(`index.md` 就在仓库根)。
260
- - 摘要最多 60 字,一句话讲清卡组主题。
261
- - 卡片数以扫描实际卡片数为准。
152
+ 正文中可以有 `![](url)` 图片,图片会正常渲染但**不参与打字**(parser 提取时跳过)。
262
153
 
263
- ### `log.md` 格式
154
+ #### type: snippet
264
155
 
265
- `log.md` 在仓库根,按时间顺序追加(新条目追加在文件末尾),**绝不删除条目**。每次操作**必须**追加一条。
156
+ 短章卡。**结构和 article 完全一样**(H1 = 标题不打,H1 之下 = 打字目标),区别只在渲染:snippet 渲染时**居中显示、居中排版**,适合诗句、格言、口号、slogan、短小的独立段落。视觉上比 article 更像"海报"。
266
157
 
267
158
  ```md
268
- ---
269
- updated: YYYY-MM-DD
270
- ---
271
-
272
- # 日志
273
-
274
- ## [YYYY-MM-DD] ingest | <源标题或新卡组名>
275
- - 新建: [卡组 A](material/<A>.md) — N 张卡片
276
- - 更新: [卡组 B](material/<B>.md) — 追加 M 张
159
+ # 静夜思
277
160
 
278
- ## [YYYY-MM-DD] quiz-gen | <主题>
279
- - 新建: [卡组 C](material/<C>.md) — N 张卡片
161
+ 床前明月光,
162
+ 疑是地上霜。
163
+ 举头望明月,
164
+ 低头思故乡。
280
165
 
281
- ## [YYYY-MM-DD] update | <卡组名>
282
- - 追加: N 张
283
- - 修正: M 张
166
+ # Simplicity is the ultimate sophistication.
284
167
 
285
- ## [YYYY-MM-DD] cascade | <触发卡组>
286
- - 影响: [卡组 X](material/<X>.md), [卡组 Y](material/<Y>.md)
287
-
288
- ## [YYYY-MM-DD] check | N 条问题,M 条自动修复
289
-
290
- ## [YYYY-MM-DD] level-up | <合并/拆分描述>
168
+ Attributed to Leonardo da Vinci.
291
169
  ```
292
170
 
293
- 规则:
294
-
295
- - 每次 ingest / update / quiz-gen / cascade / check / level-up 都写一条。
296
- - 标题行格式:`## [YYYY-MM-DD] <op> | <说明>`。
297
- - 条目**只追加**在文件末尾;不删、不改已有条目。
298
- - 可以用 `grep "^## \[" log.md` 扫全部条目。
299
-
300
- ---
301
-
302
- ## 操作
303
-
304
- ### Ingest
305
-
306
- **把原始材料变成一叠可打的卡片。**
307
-
308
- 触发:用户说 "ingest <path-or-url>"、"从这篇文章出卡片"、"处理这份词表"。
309
-
310
- **步骤 1:fetch(把源材料落到 raw/)**
311
-
312
- 四种情况:
313
-
314
- 情况 A:输入是 URL
315
- - 用可用的抓取工具下载并转为 markdown。无工具时让用户直接粘贴。
316
- - 保存到 `raw/YYYY-MM-DD-<slug>.md`。
317
- - 写入 frontmatter:`source: <URL>` + `collected: YYYY-MM-DD`。
318
-
319
- 情况 B:输入是本地文件(`ingest /path/to/wordlist.pdf`)
320
- - 转换为 markdown,复制到 `raw/YYYY-MM-DD-<slug>.md`。
321
- - 写入 frontmatter:`source: <原路径>` + `collected: YYYY-MM-DD`。
322
-
323
- 情况 C:输入是粘贴文本
324
- - 保存到 `raw/YYYY-MM-DD-note-<N>.md`。
325
- - 写入 frontmatter:`source: 粘贴文本` + `collected: YYYY-MM-DD`。
326
-
327
- 情况 D:输入是主题描述("从我的记忆里给我出 20 张 GRE 高频词")
328
- - **跳过 fetch**,直接进步骤 2(即 quiz-gen 语义,见 Quiz-gen 操作)。
329
-
330
- **步骤 2:切卡**
331
-
332
- 读源后按材料类型切分:
171
+ 选 article 还是 snippet:段落自然阅读、有上下文流 → article;短小、独立、要视觉呼吸感 → snippet。
333
172
 
334
- - **词表** → 每个词一张 word 卡。IPA 从材料里抓;材料没给就查权威来源,实在不知道就留空并在 log 里报告。gloss 用简中。
335
- - **句子/例句集** → 每句一张 sentence 卡。translation 从材料里抓或自然翻译。
336
- - **文章 / 教程 / 代码片段** → 提炼要点,出 normal 卡。Q 是问题,A 是简短答案。避免答案超过 200 字符——超了拆成多张。
173
+ #### type: qa
337
174
 
338
- **步骤 3:判断卡组归属**
175
+ 问答卡。**H1 = 卡片名,`## Q` = 题干,`## A` = 打字目标**。
339
176
 
340
- - 扫 `material/` 下现有卡组,找主题最贴近的:
341
- - 已有卡组主题一致且卡片数 < 50 → 追加到已有卡组。
342
- - 已有卡组主题一致但卡片数 ≥ 50 → 新建同主题的续集卡组(如 `gre-vocab-list-4.md`)。
343
- - 没有对应卡组 → 新建 `material/<slug>.md`,写 deck 文件头 frontmatter。
344
- - **一个 deck 只装一个主题**——不允许把 TypeScript 和英语单词混一起。
345
-
346
- **步骤 4:验证可打性**
347
-
348
- 对每张新卡片的 `## A:`:
349
-
350
- - 扫描字符,剔除 emoji、零宽、控制字符(除 Tab / Enter 外)。
351
- - 全角标点交给工具自动规范化——你按自然写法写即可,不必手改。
352
- - 长度 > 200 字符 → 拆成多张卡片,Q 段各写不同侧面提示。
353
- - 单词卡的 A 段应等于 Q 段的目标词(练拼写,不是练释义)。
354
-
355
- **步骤 5:更新 index.md 和 log.md**
356
-
357
- - index.md:新建卡组加条目;追加卡片的卡组更新 `卡片数` 和 `updated`。见 Index 格式节。
358
- - log.md:追加一条 ingest 记录。见 Log 格式节。
359
-
360
- **步骤 6:告知用户**
361
-
362
- 在对话里简短汇报本次 ingest 做了什么(新建/追加/总卡片数),让用户通过 `git diff` 审阅后自行 commit。
363
-
364
- **Agent 不主动 `git add` / `git commit` / `git push`**。
365
-
366
- **不做的事**
367
-
368
- - **不要**"先 preview 再等用户确认"。直接按规则写。
369
- - **不要**同时 ingest 多个源。一次一个,避免主题判断相互干扰。
370
- - **不要**在同一卡组里混主题——宁可多建几个卡组。
371
-
372
- ### Update
373
-
374
- **修正、增补现有卡组。**
375
-
376
- 触发:用户说 "给 `<deck>` 加几张关于 X 的卡片"、"修一下 `<deck>` 里 abandon 那张的 IPA"、"把这几张卡合到 `<deck>`"。
377
-
378
- **步骤**
379
-
380
- 1. **读目标卡组**:定位到要改的卡片或要追加的位置。
381
- 2. **改动**:
382
- - **追加**:新卡片按格式规范加到文件末尾(卡片之间用 `---` 分隔)。
383
- - **修正**:只改指定字段或指定卡片的 Q/A/frontmatter。**不动**没被要求改的卡片。
384
- - **删除**:明确要求删除时才删;不主动整理。
385
- 3. **验证可打性**:同 Ingest 步骤 4。
386
- 4. **bump deck 文件头 frontmatter 的 `updated`**。
387
- 5. **更新 index.md**:卡片数变了就更新 `卡片数` 和 `updated`。
388
- 6. **追加 log.md**:`## [YYYY-MM-DD] update | <卡组名>` + 追加/修正数量。
389
-
390
- **不做的事**
391
-
392
- - **不改**用户手写的卡片——见守则里的 `<!-- hand-edited -->` 标记规则。
393
- - **不趁机重整**没被要求改的部分。
394
- - **不整体重写**——除非用户明确说"重写这个卡组"。
395
-
396
- ### Cascade
397
-
398
- **大改动之后,检查关联卡组。**
399
-
400
- 触发:Ingest 或 Update 涉及**大量卡片**(≥ 10 张)、**改主题范围**(如某卡组从"GRE 词表"变成"GRE + TOEFL 混合")、或**改术语命名**时自动执行。
401
-
402
- **步骤**
403
-
404
- 1. **扫 index.md**:找出与刚改动的卡组共享 tag 或主题相近的其他卡组。
405
- 2. **逐个检查**:
406
- - 术语一致性:新卡组用了新术语,旧卡组是否需要跟进(例如新卡组把 `useState` 改叫 `React state hook`,旧卡组要不要统一)。
407
- - 重复卡片:新卡组的卡片是否和旧卡组重复;重复的从新卡组删(保留旧的)或者反过来(保留质量更好的)。
408
- - IPA / gloss / translation 冲突:同一个词/句在多个卡组里,字段应一致。
409
- 3. **修正冲突**:优先"以新为准"或"以质量高者为准"。改动**只限**冲突项,不重整。
410
- 4. **每个被改动的卡组 bump `updated`**。
411
- 5. **追加 log.md**:`## [YYYY-MM-DD] cascade | <触发卡组>` + 影响列表。
412
-
413
- Cascade 在**触发操作结束前**完成,不推后。
414
-
415
- ### Quiz-gen
416
-
417
- **从主题描述凭空造一叠卡片。**
418
-
419
- 触发:用户说 "quiz-gen JavaScript closures"、"给我出 30 张 GRE 高频词"、"造一叠 React hooks 的题"。
420
-
421
- **步骤**
422
-
423
- 1. **确认主题和数量**:默认 25 张,用户指定就按用户指定的。
424
- 2. **选卡片类型**:
425
- - 词汇/单词 → word 卡为主。
426
- - 语言学习句子 → sentence 卡为主。
427
- - 编程概念 / 知识点 → normal 卡(Q 是问题,A 是简短答案)。
428
- 3. **按 Ingest 步骤 2-6 走**:切卡 → 判断卡组归属(通常新建卡组)→ 验证可打性 → 更新 index / log。
429
- 4. **log 里用 `quiz-gen` 而不是 `ingest`**,标明来源是"训练记忆"。
430
-
431
- **规则**
432
-
433
- - 内容必须准确——不确定的(比如冷门词的 IPA)宁可留空 + 备注,不要瞎编。
434
- - 一次一个主题、一个卡组。不同主题分多次 quiz-gen。
177
+ ```md
178
+ # 闭包
435
179
 
436
- ### Check
180
+ ## Q
181
+ 什么是 JavaScript 中的闭包?请举一个实际例子。
437
182
 
438
- **用户跑 `qtype check` 报错时,Agent 修。**
183
+ ## A
184
+ 闭包是函数与其词法作用域的组合。当内部函数被外部引用时,词法作用域中的变量被保留在内存中。常见例子是计数器函数。
185
+ ```
439
186
 
440
- 触发:用户跑 `qtype check`(详见 CLI 节),命令报错并把错误列表给 Agent。
187
+ | 层级 | 内容 |
188
+ |---|---|
189
+ | **H1** | 卡片名(不打) |
190
+ | **`## Q`** | 题干(markdown,可含图片,不打) |
191
+ | **`## A`** | 打字目标(markdown) |
441
192
 
442
- **Agent 分类处理**:
193
+ #### type: code
443
194
 
444
- **确定性问题(自动修)**:
195
+ 代码题。**同 qa 结构**,A 段里预期有 fenced code block,代码块内容 = 打字目标。
445
196
 
446
- - **不合法字符**:卡片答案含 emoji / 零宽 / 控制字符 → 删掉该字符或整张卡片(视上下文决定)。
447
- - **frontmatter 字段错误**:字段名拼错、类型错、缺必填字段 → 修字段。
448
- - **单词卡缺 phonetic/gloss、句子卡缺 translation** → 补上(补不出来时用 `TODO` 占位并在对话里报告)。
449
- - **答案 > 200 字符** → 拆成多张卡片,Q 段各写不同侧面提示。
450
- - **index.md 一致性**:卡组文件存在但 index 里没有 → 加条目;卡组数变了 → 更新 `卡片数`。
451
- - **内部链接失效**:目标不存在 → 搜 `material/` 下同名文件,唯一匹配则修;否则报告。
197
+ ````md
198
+ # Two Sum
452
199
 
453
- **启发式问题(只报告)**:
200
+ ## Q
201
+ 给你一个整数数组 nums 和一个目标值 target,找出和为目标值的那两个整数的下标。
454
202
 
455
- - **重复卡片**:不同卡组里出现相同 Q + A 组合。报告,让用户决定合并还是保留。
456
- - **卡组过大**:卡片数 > 100 → 建议拆分。
457
- - **卡组过小**:卡片数 < 5 → 建议合并到相近卡组。
458
- - **孤立卡组**:卡组的 tag 在 index.md 里只被这一个卡组使用。可能是新主题,也可能是分类错。报告。
203
+ ## A
204
+ ```py
205
+ class Solution:
206
+ def twoSum(self, nums, target):
207
+ seen = {}
208
+ for i, x in enumerate(nums):
209
+ if target - x in seen:
210
+ return [seen[target - x], i]
211
+ seen[x] = i
212
+ ```
213
+ ````
459
214
 
460
- **报告与日志**:给用户输出修复报告,末尾追加 `## [YYYY-MM-DD] check | N 条问题,M 条自动修复`。
215
+ | 层级 | 内容 |
216
+ |---|---|
217
+ | **H1** | 题目名(不打) |
218
+ | **`## Q`** | 题干(markdown,不打) |
219
+ | **`## A`** | 包含一个 fenced code block;**代码内容 = 打字目标** |
461
220
 
462
- ### Level-up
221
+ 代码块的语言 tag 用于 Shiki 高亮(`ts` / `py` / `go` 等)。
463
222
 
464
- **把散乱小卡组重构成有序的系列。**
223
+ ### 通用规则
465
224
 
466
- 触发:用户说 "把这几个卡组合起来"、"这个卡组拆成初级/进阶两个"、"把 GRE 词表整理成 list 1/2/3"
225
+ - **卡片作者不用记"音标必须 inline code"这种约定**:结构一目了然
226
+ - 打字目标里可以出现空格、换行(Enter)、Tab
227
+ - 长度**建议**不超过 200 字符(每卡)——过长影响体验,拆卡
228
+ - 只允许 OS 键盘(含中文 IME)能打出的字符
229
+ - 全角中文标点会被工具自动规范化
467
230
 
468
- **步骤**
231
+ ### 富渲染(题干 / 正文可用,不参与打字)
469
232
 
470
- 1. **读涉及的卡组**:全部 frontmatter + 全部卡片。
471
- 2. **决定切分策略**:
472
- - **合并**:多个小卡组 → 一个大卡组(按主题、按难度、按标签合并)。
473
- - **拆分**:一个大卡组 → 多个小卡组(按难度分级、按子主题分类)。
474
- - **重排序**:卡组内顺序调整——例如按 difficulty 升序、按字母序、按学习先后。
475
- 3. **写新的卡组文件**:新文件按 deck 命名规则命名(如 `gre-vocab-list-1.md`)。
476
- 4. **删除或清空旧卡组**:合并后旧文件删除;拆分后旧文件删除。**Agent 用 `rm`**(不主动 `git rm`)。
477
- 5. **更新 index.md 和 log.md**:条目变化、链接更新、追加 `## [YYYY-MM-DD] level-up | <描述>`。
478
- 6. **保留卡片本体**:不改卡片的 Q / A / IPA / gloss / translation——level-up 只重组,不改内容。用户手写的卡片(见守则)原样搬迁。
233
+ 打字目标之外的展示位置(`## Q` 题干、article / snippet 正文、gloss)支持 3 种富内容:
479
234
 
480
- **不做的事**
235
+ - **Mermaid 流程图**:` ```mermaid ` 代码块,`publish build` 预渲染 SVG
236
+ - **数学公式**:行内 `$…$`,块级 `$$…$$`,KaTeX 懒加载渲染(~280KB)
237
+ - **代码块 / 图片 / 粗斜体**:标准 markdown
481
238
 
482
- - **不趁机改卡片内容**。level-up 只重组。要改内容用 Update。
483
- - **不删用户数据**:如果不确定要不要删旧文件,问用户。
239
+ 举例(`## Q` 里放公式,`## A` 打 ASCII):
484
240
 
241
+ ```md
242
+ ---
243
+ type: qa
244
+ tags: [数学]
485
245
  ---
486
246
 
487
- ## 守则
488
-
489
- ### 禁令
490
-
491
- 以下行为**严格禁止**:
247
+ # 高斯积分
492
248
 
493
- 1. **不改 raw/ 内容**:raw 下文件默认只读。除移动、重命名、删除外,改正文都要等用户明确要求。
494
- 2. **不写不可打字符**:卡片答案里 emoji / 零宽字符 / 控制字符(除 Tab、Enter 外)一律禁止。不确定的字符宁可换成 ASCII 或不写。
495
- 3. **不写太长的答案**:`## A:` 建议 ≤ 200 字符。长了拆卡片,别让用户敲十分钟。
496
- 4. **不混主题**:一个 deck 只装一个主题——TypeScript 和英语单词不能塞一个文件。宁可多建几个 deck。
497
- 5. **不改用户手写卡片**:卡片正文含 `<!-- hand-edited -->` HTML 注释的,Agent 只能读、不能改。要改必须先问用户。cascade 遇到这种卡片时跳过。
498
- 6. **不用 Wikilink**:`[[foo]]` 语法禁用,只用 `[文本](./路径.md)`。
499
- 7. **不绝对路径**:所有链接必须相对路径,以 `./` 或 `../` 开头。
500
- 8. **不主动 git commit / push**:所有 commit 由用户决定。
501
- 9. **不建规则外的目录**:`material/` 下只允许平铺的 `.md` 文件和 `assets/` 子目录;`raw/` 下只允许平铺的 `.md` 和 `assets/` 子目录。其他结构(如 `material/words/`、`material/2026/`)都禁止。
502
- 10. **不凭空造 IPA / 释义 / 翻译**:不确定的字段宁可空着并在 log 里报告,不要编。
249
+ ## Q
250
+ 求以下积分:
503
251
 
504
- ### 内容语言
252
+ $$\int_{-\infty}^{\infty} e^{-x^2}\,dx = ?$$
505
253
 
506
- - 卡组的 `title`、`index.md` 摘要、`log.md` 条目:**中文为主,专业术语保留原文**。
507
- - 单词卡的 `gloss`:**简中**。
508
- - 句子卡的 `translation`:翻译到用户的母语(默认简中)。表意即可,不必逐字对齐。
509
- - 卡片的 `## A:` 答案文本本身:**由目标语言决定**,保留材料原样(英语词就是英语,日语句就是日语)。
254
+ ## A
255
+ sqrt(pi)
256
+ ```
510
257
 
511
- ### 卡片数量指导
258
+ **渲染只在展示侧发生,打字目标(`## A` / word 的 H1 / 等等)依然只能是键盘能敲的字符**。
512
259
 
513
- - **一个卡组 20–50 张**是甜蜜区。
514
- - < 5 张:太薄,考虑合并(Level-up)。
515
- - \> 100 张:太厚,考虑拆分(Level-up)。
516
- - 一次 Ingest / Quiz-gen 生成的卡组通常 25 张左右——写多了反而质量下降。
260
+ ### 命名
517
261
 
518
- ### 难度分级
262
+ **素材文件名**:`material/<slug>.md`
519
263
 
520
- `difficulty` 字段的语义(默认 3):
264
+ - `<slug>`:主题的 kebab-case,小写,英文字母和短横线,最长 60 字符
265
+ - 中文主题用英译或拼音
266
+ - 同名冲突:末尾追加 `-2` / `-3`
521
267
 
522
- | 值 | 含义 |
523
- |---|---|
524
- | 1 | 极易识别,无需思考(如常见词、常识事实) |
525
- | 2 | 一眼可读,无需回忆(如常用短语、基础语法) |
526
- | 3 | 需要短暂回忆(默认,多数卡片) |
527
- | 4 | 需要认真思考或较长答案(如概念解释、句子造句) |
528
- | 5 | 高难度,长答案或复杂概念(如小段代码、长句默写) |
268
+ ### 链接
529
269
 
530
- ### 快速参考
270
+ - **只用 Markdown link**,不用 Wikilink
271
+ - **绝不**用绝对路径(不以 `./` 或 `../` 开头的都不行)
272
+ - 链接目标必须实际存在
531
273
 
532
- **Ingest 一个源**:
274
+ ### index.md 格式
533
275
 
534
- ```
535
- raw/YYYY-MM-DD-<slug>.md ← 写源(平铺,可选)
536
- material/<slug>.md ← 写或追加卡组
537
- index.md ← 更新表格(卡片数 / updated)
538
- log.md ← 追加 ## [日期] ingest | 标题
539
- ```
276
+ 按标签分组,每次改动同步更新:
540
277
 
541
- **Update 一个卡组**:
278
+ ```md
279
+ ---
280
+ updated: YYYY-MM-DD
281
+ ---
542
282
 
543
- ```
544
- material/<slug>.md ← 追加/修正卡片,bump updated
545
- index.md ← 更新卡片数和 updated
546
- log.md ← 追加 ## [日期] update | 卡组名
547
- ```
283
+ # 索引
548
284
 
549
- **Quiz-gen 从主题**:
285
+ ## <标签 1>
550
286
 
551
- ```
552
- material/<slug>.md ← 新建卡组
553
- index.md 加条目
554
- log.md ← 追加 ## [日期] quiz-gen | 主题
287
+ | 素材 | 类型 | 卡片数 | 摘要 | 更新 |
288
+ |---|---|---|---|---|
289
+ | [标题 1](material/<文件 1>.md) | word | 32 | 摘要 | YYYY-MM-DD |
555
290
  ```
556
291
 
557
- **Check 用户报错时**:
292
+ ### log.md 格式
558
293
 
559
- ```
560
- 按错误列表分类修
561
- 自动修:字符 / frontmatter / 长度 / index 一致性
562
- 只报告:重复卡片 / 过大过小 / 孤立卡组
563
- log.md ← 追加 ## [日期] check | N 条问题
564
- ```
294
+ 只追加:
565
295
 
566
- **Level-up 重构**:
567
-
568
- ```
569
- 读旧卡组 → 决策合并/拆分/重排
570
- 写新 material/*.md
571
- rm 旧文件
572
- index.md ← 条目增减
573
- log.md ← 追加 ## [日期] level-up | 描述
296
+ ```md
297
+ ## [YYYY-MM-DD] ingest | <来源>
298
+ - 新建: [素材 A](material/<A>.md) — N 张卡片
574
299
  ```
575
300
 
576
301
  ---
577
302
 
578
- ## 给用户的 CLI 命令(不是给你的)
579
-
580
- 以下命令由**用户**在终端运行,你写内容时不要尝试调用,但要知道它们存在——用户报错时你需要能识别。
303
+ ## 操作
581
304
 
582
- | 命令 | 作用 |
583
- |---|---|
584
- | `qtype check` | 校验仓库:扫**不可打字符**、**frontmatter 缺失/错**、**答案过长**、**index 不一致**(致命)+ 重复卡片 / 过大过小卡组(警告)。**不写任何文件**。 |
585
- | `qtype publish build` | 把仓库构建成静态站到 `dist/`。 |
586
- | `qtype publish serve` | 本地起服务,用浏览器进入练习界面。支持中文 IME、目标 WPM 光标、blind / ghost 提示模式。 |
587
- | `qtype publish init --ci github` | 生成 GitHub Actions workflow。 |
305
+ ### Ingest / Update / Quiz-gen / Cascade / Check / Level-up
588
306
 
589
- **注意**:
307
+ (保留原有语义 — 见操作节完整说明。核心变化:每次生成 material 时**先决定 type**,然后按对应结构写卡。)
590
308
 
591
- - 你在 ingest / update / quiz-gen 后**不需要**主动跑这些命令;用户 commit 时 CI 会跑。
592
- - 用户报 "check 说 XXX 卡片有非法字符",定位到卡片并按 Check 操作节修。
593
- - 用户报 "publish serve 里练不了这张卡" — 通常是 A 段含不可打字符或者长度超限——按 Check 修。
309
+ ### 决定 type
594
310
 
595
- ---
311
+ - 单词、词组、短语 → **word**
312
+ - 单句、名言、格言 → **sentence**
313
+ - 段落、文章、诗词 → **article**
314
+ - 问答、面试题、概念解释 → **qa**
315
+ - 代码题、算法题、片段 → **code**
596
316
 
597
- ## 发布产物(仅作背景知识)
317
+ **一个 material 只有一个 type**。混合内容拆成多个 material。
598
318
 
599
- `qtype publish build` 输出大致:
600
-
601
- ```
602
- dist/
603
- ├── index.html ← SPA shell
604
- ├── material/<slug>.html ← 每卡组一个 shell(<noscript> 内嵌纯 HTML 兜底)
605
- ├── _app/ ← view bundle
606
- │ └── app.js + chunks/...
607
- └── _data/
608
- └── repo.json ← 单一数据快照(卡组 / 卡片 / 元数据)
609
- ```
319
+ ---
610
320
 
611
- Web UI 支持:中文 IME 输入(提交后与目标 diff)、三种卡片类型(`type: normal | word | sentence`)、目标速度光标、blind / ghost 提示、全角标点自动规范化、空格 / Enter / Tab 字符输入。
321
+ ## 守则
612
322
 
613
- **致命错误**:build 在以下情况会直接 throw 中止:
323
+ ### 禁令
614
324
 
615
- - 任一卡片答案含不可打字符
616
- - 任一卡片 frontmatter 缺必填字段或字段类型错
617
- - deck 文件头 frontmatter `title` / `language` / `tags`
618
- - 单词卡缺 `phonetic` / `gloss`,句子卡缺 `translation`
325
+ 1. **不改 raw/ 内容**:默认只读
326
+ 2. **不写不可打字符**:emoji / 零宽字符 / 控制字符(除 Tab、Enter 外)禁止
327
+ 3. **不写太长的答案**:`## A:` article 正文建议 200 字符
328
+ 4. **不混主题**:一个 material 只装一个主题
329
+ 5. **不改用户手写卡片**:卡片正文含 `<!-- hand-edited -->` HTML 注释的 Agent 只能读、不能改
330
+ 6. **不用 Wikilink**
331
+ 7. **不绝对路径**
332
+ 8. **不主动 git commit / push**
333
+ 9. **不建规则外的目录**
334
+ 10. **不凭空造 IPA / 释义 / 翻译**:不确定的宁可空着
335
+ 11. **一个 material 只有一个 type**:不能混
336
+ 12. **没有 card-level frontmatter**:所有 per-card 信息都用 markdown 结构表达