cotutor 0.1.0 → 0.3.0

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 (845) hide show
  1. package/LICENSE +247 -21
  2. package/NOTICE +42 -0
  3. package/README.md +107 -24
  4. package/bin/cotutor.js +4 -4
  5. package/cards/canvas/card.css +8 -0
  6. package/cards/canvas/card.md +68 -0
  7. package/cards/choice/card.css +18 -0
  8. package/cards/choice/card.md +55 -0
  9. package/cards/code/card.css +5 -0
  10. package/cards/code/card.md +46 -0
  11. package/cards/dictation/card.css +10 -0
  12. package/cards/dictation/card.md +97 -0
  13. package/cards/image/card.css +10 -0
  14. package/cards/image/card.md +52 -0
  15. package/cards/lecture/card.css +9 -0
  16. package/cards/lecture/card.md +69 -0
  17. package/cards/paint/card.css +20 -0
  18. package/cards/paint/card.md +77 -0
  19. package/cards/photo/card.css +15 -0
  20. package/cards/photo/card.md +61 -0
  21. package/cards/read/card.css +6 -0
  22. package/cards/read/card.md +51 -0
  23. package/cards/text/card.css +3 -0
  24. package/cards/text/card.md +69 -0
  25. package/cards/tianzige/card.css +17 -0
  26. package/cards/tianzige/card.md +78 -0
  27. package/cards/tutor/card.css +66 -0
  28. package/cards/tutor/card.md +148 -0
  29. package/cards/word/card.css +24 -0
  30. package/cards/word/card.md +91 -0
  31. package/cards//346/235/277/344/271/246/346/200/216/344/271/210/345/206/231.md +159 -0
  32. package/dist/app/activity-eval-rules.d.ts +62 -0
  33. package/dist/app/activity-eval-rules.js +276 -0
  34. package/dist/app/activity-eval.d.ts +65 -0
  35. package/dist/app/activity-eval.js +158 -0
  36. package/dist/app/build.d.ts +11 -0
  37. package/dist/app/build.js +45 -0
  38. package/dist/app/cli/activities.d.ts +63 -0
  39. package/dist/app/cli/activities.js +158 -0
  40. package/dist/app/cli/cert.d.ts +7 -0
  41. package/dist/app/cli/cert.js +36 -0
  42. package/dist/app/cli/chalk/bake.d.ts +10 -0
  43. package/dist/app/cli/chalk/bake.js +58 -0
  44. package/dist/app/cli/chalk/browser.d.ts +16 -0
  45. package/dist/app/cli/chalk/browser.js +142 -0
  46. package/dist/app/cli/chalk/build.d.ts +14 -0
  47. package/dist/app/cli/chalk/build.js +100 -0
  48. package/dist/app/cli/chalk/dub.d.ts +51 -0
  49. package/dist/app/cli/chalk/dub.js +106 -0
  50. package/dist/app/cli/chalk/load-scene.d.ts +34 -0
  51. package/dist/app/cli/chalk/load-scene.js +117 -0
  52. package/dist/app/cli/chalk/main.d.ts +7 -0
  53. package/dist/app/cli/chalk/main.js +198 -0
  54. package/dist/app/cli/chalk/serve.d.ts +4 -0
  55. package/dist/app/cli/chalk/serve.js +28 -0
  56. package/dist/app/cli/chalk/snap.d.ts +65 -0
  57. package/dist/app/cli/chalk/snap.js +103 -0
  58. package/dist/app/cli/chalk/typecheck.d.ts +7 -0
  59. package/dist/app/cli/chalk/typecheck.js +51 -0
  60. package/dist/app/cli/doctor.d.ts +23 -0
  61. package/dist/app/cli/doctor.js +617 -0
  62. package/dist/app/cli/grades.d.ts +14 -0
  63. package/dist/app/cli/grades.js +44 -0
  64. package/dist/{cli → app/cli}/init.d.ts +3 -1
  65. package/dist/app/cli/init.js +155 -0
  66. package/dist/app/cli/main.js +715 -0
  67. package/dist/app/cli/migrate.d.ts +58 -0
  68. package/dist/app/cli/migrate.js +253 -0
  69. package/dist/app/cli/serve.d.ts +37 -0
  70. package/dist/app/cli/serve.js +98 -0
  71. package/dist/app/cli/shipped.d.ts +30 -0
  72. package/dist/app/cli/shipped.js +47 -0
  73. package/dist/app/cli/skeleton.d.ts +38 -0
  74. package/dist/app/cli/skeleton.js +161 -0
  75. package/dist/app/cli/skills.d.ts +55 -0
  76. package/dist/app/cli/skills.js +189 -0
  77. package/dist/app/cli/themes.d.ts +52 -0
  78. package/dist/app/cli/themes.js +148 -0
  79. package/dist/app/cli/tutors.d.ts +73 -0
  80. package/dist/app/cli/tutors.js +250 -0
  81. package/dist/app/cli/usage.d.ts +2 -0
  82. package/dist/app/cli/usage.js +30 -0
  83. package/dist/app/dictation/recognize.d.ts +18 -0
  84. package/dist/app/dictation/recognize.js +6 -0
  85. package/dist/app/dictation/route.d.ts +52 -0
  86. package/dist/app/dictation/route.js +510 -0
  87. package/dist/app/diff.d.ts +11 -0
  88. package/dist/app/diff.js +71 -0
  89. package/dist/app/http/access.d.ts +62 -0
  90. package/dist/app/http/access.js +180 -0
  91. package/dist/app/http/app.d.ts +246 -0
  92. package/dist/app/http/app.js +1212 -0
  93. package/dist/app/http/dev-activities.d.ts +115 -0
  94. package/dist/app/http/dev-activities.js +193 -0
  95. package/dist/app/http/dev-overview.d.ts +108 -0
  96. package/dist/app/http/dev-overview.js +209 -0
  97. package/dist/app/http/dev-tutor-files.d.ts +80 -0
  98. package/dist/app/http/dev-tutor-files.js +151 -0
  99. package/dist/app/http/parent-home.d.ts +37 -0
  100. package/dist/app/http/parent-home.js +203 -0
  101. package/dist/app/http/range.d.ts +9 -0
  102. package/dist/app/http/range.js +19 -0
  103. package/dist/app/http/raw-view.d.ts +117 -0
  104. package/dist/app/http/raw-view.js +149 -0
  105. package/dist/app/http/send-file.d.ts +7 -0
  106. package/dist/app/http/send-file.js +29 -0
  107. package/dist/app/http/stage.d.ts +24 -0
  108. package/dist/app/http/stage.js +97 -0
  109. package/dist/app/http/theme.d.ts +13 -0
  110. package/dist/app/http/theme.js +41 -0
  111. package/dist/app/machine/bailian.d.ts +28 -0
  112. package/dist/app/machine/bailian.js +88 -0
  113. package/dist/app/mock/mock-live.d.ts +16 -0
  114. package/dist/app/mock/mock-live.js +140 -0
  115. package/dist/app/mock/mock.d.ts +89 -0
  116. package/dist/app/mock/mock.js +1117 -0
  117. package/dist/app/replay.d.ts +94 -0
  118. package/dist/app/replay.js +170 -0
  119. package/dist/app/skills/analyze-doc.d.ts +3 -0
  120. package/dist/app/skills/analyze-doc.js +47 -0
  121. package/dist/app/skills/home-doc.d.ts +5 -0
  122. package/dist/app/skills/home-doc.js +112 -0
  123. package/dist/app/skills/tune-doc.d.ts +3 -0
  124. package/dist/app/skills/tune-doc.js +80 -0
  125. package/dist/app/talk/list.d.ts +11 -0
  126. package/dist/app/talk/list.js +9 -0
  127. package/dist/app/talk/route.d.ts +16 -0
  128. package/dist/app/talk/route.js +142 -0
  129. package/dist/app/workspace.d.ts +58 -0
  130. package/dist/{cli → app}/workspace.js +82 -36
  131. package/dist/app/ws/route.d.ts +25 -0
  132. package/dist/app/ws/route.js +29 -0
  133. package/dist/app/ws/ws.d.ts +31 -0
  134. package/dist/app/ws/ws.js +169 -0
  135. package/dist/board/canvas-chat.d.ts +97 -0
  136. package/dist/board/canvas-chat.js +175 -0
  137. package/dist/board/card-guards.d.ts +15 -0
  138. package/dist/board/card-guards.js +38 -0
  139. package/dist/board/cards/canvas.d.ts +41 -0
  140. package/dist/board/cards/canvas.js +83 -0
  141. package/dist/board/cards/choice.d.ts +20 -0
  142. package/dist/board/cards/choice.js +64 -0
  143. package/dist/board/cards/code.d.ts +9 -0
  144. package/dist/board/cards/code.js +10 -0
  145. package/dist/board/cards/dictation.d.ts +42 -0
  146. package/dist/board/cards/dictation.js +105 -0
  147. package/dist/board/cards/docs.d.ts +47 -0
  148. package/dist/board/cards/docs.js +152 -0
  149. package/dist/board/cards/image.d.ts +13 -0
  150. package/dist/board/cards/image.js +26 -0
  151. package/dist/board/cards/index.d.ts +62 -0
  152. package/dist/board/cards/index.js +144 -0
  153. package/dist/board/cards/kind.d.ts +33 -0
  154. package/dist/board/cards/kind.js +9 -0
  155. package/dist/board/cards/lecture.d.ts +26 -0
  156. package/dist/board/cards/lecture.js +62 -0
  157. package/dist/board/cards/paint.d.ts +38 -0
  158. package/dist/board/cards/paint.js +85 -0
  159. package/dist/board/cards/photo.d.ts +15 -0
  160. package/dist/board/cards/photo.js +29 -0
  161. package/dist/board/cards/read.d.ts +8 -0
  162. package/dist/board/cards/read.js +18 -0
  163. package/dist/board/cards/text.d.ts +20 -0
  164. package/dist/board/cards/text.js +59 -0
  165. package/dist/board/cards/tianzige.d.ts +16 -0
  166. package/dist/board/cards/tianzige.js +64 -0
  167. package/dist/board/cards/tutor.d.ts +72 -0
  168. package/dist/board/cards/tutor.js +134 -0
  169. package/dist/board/cards/word.d.ts +20 -0
  170. package/dist/board/cards/word.js +76 -0
  171. package/dist/board/lecture.d.ts +100 -0
  172. package/dist/board/lecture.js +204 -0
  173. package/dist/board/paper.d.ts +20 -0
  174. package/dist/board/paper.js +76 -0
  175. package/dist/board/parse.d.ts +120 -0
  176. package/dist/board/parse.js +330 -0
  177. package/dist/board/presentation.d.ts +295 -0
  178. package/dist/board/presentation.js +615 -0
  179. package/dist/board/sections.d.ts +16 -0
  180. package/dist/board/sections.js +130 -0
  181. package/dist/brain/api-tools.d.ts +8 -0
  182. package/dist/brain/api-tools.js +190 -0
  183. package/dist/brain/api.d.ts +62 -0
  184. package/dist/brain/api.js +411 -0
  185. package/dist/brain/cli/adapters.d.ts +60 -0
  186. package/dist/brain/cli/adapters.js +91 -0
  187. package/dist/brain/cli/qwen.d.ts +11 -0
  188. package/dist/brain/cli/qwen.js +141 -0
  189. package/dist/brain/cli/run-plan.d.ts +59 -0
  190. package/dist/brain/cli/run-plan.js +71 -0
  191. package/dist/brain/cli/run.d.ts +35 -0
  192. package/dist/brain/cli/run.js +256 -0
  193. package/dist/brain/cli/stream-json.d.ts +18 -0
  194. package/dist/brain/cli/stream-json.js +86 -0
  195. package/dist/brain/cli/types.d.ts +144 -0
  196. package/dist/brain/cli/types.js +3 -0
  197. package/dist/brain/cli/warm.d.ts +53 -0
  198. package/dist/brain/cli/warm.js +103 -0
  199. package/dist/brain/index.d.ts +145 -0
  200. package/dist/brain/index.js +74 -0
  201. package/dist/brain/stream.d.ts +20 -0
  202. package/dist/brain/stream.js +70 -0
  203. package/dist/brain/transcript.d.ts +45 -0
  204. package/dist/brain/transcript.js +132 -0
  205. package/dist/chalk/actions.d.ts +37 -0
  206. package/dist/chalk/actions.js +69 -0
  207. package/dist/chalk/bundle.d.ts +26 -0
  208. package/dist/chalk/bundle.js +69 -0
  209. package/dist/chalk/check.d.ts +28 -0
  210. package/dist/chalk/check.js +291 -0
  211. package/dist/chalk/circle.d.ts +64 -0
  212. package/dist/chalk/circle.js +193 -0
  213. package/dist/chalk/clock.d.ts +84 -0
  214. package/dist/chalk/clock.js +84 -0
  215. package/dist/chalk/geometry.d.ts +44 -0
  216. package/dist/chalk/geometry.js +139 -0
  217. package/dist/chalk/glyphs/capitals.d.ts +12 -0
  218. package/dist/chalk/glyphs/capitals.js +264 -0
  219. package/dist/chalk/glyphs/index.d.ts +21 -0
  220. package/dist/chalk/glyphs/index.js +18 -0
  221. package/dist/chalk/glyphs/letters.d.ts +13 -0
  222. package/dist/chalk/glyphs/letters.js +280 -0
  223. package/dist/chalk/glyphs/metrics.d.ts +33 -0
  224. package/dist/chalk/glyphs/metrics.js +28 -0
  225. package/dist/chalk/glyphs/registry.d.ts +7 -0
  226. package/dist/chalk/glyphs/registry.js +8 -0
  227. package/dist/chalk/glyphs/sample.d.ts +32 -0
  228. package/dist/chalk/glyphs/sample.js +102 -0
  229. package/dist/chalk/glyphs/skeleton.d.ts +64 -0
  230. package/dist/chalk/glyphs/skeleton.js +126 -0
  231. package/dist/chalk/glyphs/types.d.ts +58 -0
  232. package/dist/chalk/glyphs/types.js +17 -0
  233. package/dist/chalk/index.d.ts +23 -0
  234. package/dist/chalk/index.js +15 -0
  235. package/dist/chalk/manifest.d.ts +41 -0
  236. package/dist/chalk/manifest.js +6 -0
  237. package/dist/chalk/paint.d.ts +180 -0
  238. package/dist/chalk/paint.js +210 -0
  239. package/dist/chalk/pointer.d.ts +8 -0
  240. package/dist/chalk/pointer.js +21 -0
  241. package/dist/chalk/prepare.d.ts +11 -0
  242. package/dist/chalk/prepare.js +15 -0
  243. package/dist/chalk/scene-schema.d.ts +199 -0
  244. package/dist/chalk/scene-schema.js +91 -0
  245. package/dist/chalk/seed.d.ts +3 -0
  246. package/dist/chalk/seed.js +10 -0
  247. package/dist/chalk/text-metrics.d.ts +8 -0
  248. package/dist/chalk/text-metrics.js +156 -0
  249. package/dist/chalk/timeline.d.ts +47 -0
  250. package/dist/chalk/timeline.js +84 -0
  251. package/dist/chalk/types.d.ts +150 -0
  252. package/dist/chalk/types.js +8 -0
  253. package/dist/lib/index.d.ts +14 -8
  254. package/dist/lib/index.js +14 -8
  255. package/dist/media/draw.d.ts +23 -0
  256. package/dist/media/draw.js +44 -0
  257. package/dist/media/mp3.d.ts +6 -0
  258. package/dist/media/mp3.js +58 -0
  259. package/dist/media/mp4.d.ts +1 -0
  260. package/dist/media/mp4.js +58 -0
  261. package/dist/media/tts-voices.d.ts +18 -0
  262. package/dist/media/tts-voices.js +606 -0
  263. package/dist/media/tts.d.ts +56 -0
  264. package/dist/media/tts.js +174 -0
  265. package/dist/media/vision.d.ts +25 -0
  266. package/dist/media/vision.js +71 -0
  267. package/dist/memory/commit.d.ts +67 -0
  268. package/dist/memory/commit.js +130 -0
  269. package/dist/memory/context.d.ts +86 -0
  270. package/dist/memory/context.js +97 -0
  271. package/dist/memory/diary.d.ts +84 -0
  272. package/dist/memory/diary.js +183 -0
  273. package/dist/memory/grade.d.ts +2 -0
  274. package/dist/memory/grade.js +7 -0
  275. package/dist/{lib → memory}/plan.d.ts +3 -1
  276. package/dist/{lib → memory}/plan.js +10 -1
  277. package/dist/memory/proposals.d.ts +11 -0
  278. package/dist/memory/proposals.js +43 -0
  279. package/dist/memory/retrieval.d.ts +44 -0
  280. package/dist/memory/retrieval.js +157 -0
  281. package/dist/memory/timetable.d.ts +19 -0
  282. package/dist/memory/timetable.js +95 -0
  283. package/dist/memory/vault-notes.d.ts +165 -0
  284. package/dist/memory/vault-notes.js +359 -0
  285. package/dist/memory/vault.d.ts +70 -0
  286. package/dist/memory/vault.js +169 -0
  287. package/dist/realtime/bailian.d.ts +120 -0
  288. package/dist/realtime/bailian.js +288 -0
  289. package/dist/realtime/cues.d.ts +51 -0
  290. package/dist/realtime/cues.js +94 -0
  291. package/dist/realtime/listen.d.ts +32 -0
  292. package/dist/realtime/listen.js +53 -0
  293. package/dist/realtime/preview.d.ts +23 -0
  294. package/dist/realtime/preview.js +38 -0
  295. package/dist/realtime/prompt.d.ts +8 -0
  296. package/dist/realtime/prompt.js +13 -0
  297. package/dist/realtime/voices.d.ts +19 -0
  298. package/dist/realtime/voices.js +71 -0
  299. package/dist/runtime/activities.d.ts +17 -0
  300. package/dist/runtime/activities.js +46 -0
  301. package/dist/runtime/activity-state.d.ts +22 -0
  302. package/dist/runtime/activity-state.js +83 -0
  303. package/dist/runtime/activity.d.ts +63 -0
  304. package/dist/runtime/activity.js +428 -0
  305. package/dist/runtime/agent-file.d.ts +24 -0
  306. package/dist/runtime/agent-file.js +59 -0
  307. package/dist/runtime/auto-bookkeep.d.ts +30 -0
  308. package/dist/runtime/auto-bookkeep.js +84 -0
  309. package/dist/{lib → runtime/context}/context-pack.d.ts +3 -3
  310. package/dist/runtime/context/context-pack.js +182 -0
  311. package/dist/runtime/context/thread-digest.d.ts +4 -0
  312. package/dist/runtime/context/thread-digest.js +35 -0
  313. package/dist/runtime/context/tutor-rules.d.ts +25 -0
  314. package/dist/runtime/context/tutor-rules.js +47 -0
  315. package/dist/runtime/delivery/delivery.d.ts +94 -0
  316. package/dist/runtime/delivery/delivery.js +145 -0
  317. package/dist/runtime/delivery/playback.d.ts +25 -0
  318. package/dist/runtime/delivery/playback.js +29 -0
  319. package/dist/runtime/delivery/player.d.ts +145 -0
  320. package/dist/runtime/delivery/player.js +221 -0
  321. package/dist/runtime/delivery/queue.d.ts +89 -0
  322. package/dist/runtime/delivery/queue.js +59 -0
  323. package/dist/runtime/home/edit.d.ts +39 -0
  324. package/dist/runtime/home/edit.js +132 -0
  325. package/dist/runtime/home/home.d.ts +180 -0
  326. package/dist/runtime/home/home.js +311 -0
  327. package/dist/runtime/home/store.d.ts +142 -0
  328. package/dist/runtime/home/store.js +440 -0
  329. package/dist/runtime/journal/conversation.d.ts +46 -0
  330. package/dist/runtime/journal/conversation.js +89 -0
  331. package/dist/runtime/journal/events.d.ts +27 -0
  332. package/dist/runtime/journal/events.js +136 -0
  333. package/dist/runtime/journal/kid-log.d.ts +105 -0
  334. package/dist/runtime/journal/kid-log.js +133 -0
  335. package/dist/runtime/journal/ledger.d.ts +17 -0
  336. package/dist/{lib → runtime/journal}/ledger.js +7 -32
  337. package/dist/runtime/journal/mix.d.ts +33 -0
  338. package/dist/runtime/journal/mix.js +88 -0
  339. package/dist/runtime/journal/mouth-index.d.ts +26 -0
  340. package/dist/runtime/journal/mouth-index.js +34 -0
  341. package/dist/runtime/journal/mouth.d.ts +54 -0
  342. package/dist/runtime/journal/mouth.js +102 -0
  343. package/dist/runtime/journal/recorder.d.ts +46 -0
  344. package/dist/runtime/journal/recorder.js +58 -0
  345. package/dist/runtime/journal/store.d.ts +123 -0
  346. package/dist/runtime/journal/store.js +316 -0
  347. package/dist/runtime/kid-input.d.ts +16 -0
  348. package/dist/runtime/kid-input.js +195 -0
  349. package/dist/runtime/kid-view.d.ts +124 -0
  350. package/dist/runtime/kid-view.js +157 -0
  351. package/dist/runtime/lecture.d.ts +86 -0
  352. package/dist/runtime/lecture.js +237 -0
  353. package/dist/runtime/live/call.d.ts +219 -0
  354. package/dist/runtime/live/call.js +1211 -0
  355. package/dist/runtime/live/turns.d.ts +48 -0
  356. package/dist/runtime/live/turns.js +102 -0
  357. package/dist/runtime/runner.d.ts +289 -0
  358. package/dist/runtime/runner.js +898 -0
  359. package/dist/runtime/talk-run.d.ts +21 -0
  360. package/dist/runtime/talk-run.js +34 -0
  361. package/dist/scenes/dictation/match.d.ts +57 -0
  362. package/dist/scenes/dictation/match.js +255 -0
  363. package/dist/scenes/dictation/recognize.d.ts +86 -0
  364. package/dist/scenes/dictation/recognize.js +163 -0
  365. package/dist/scenes/dictation/store.d.ts +112 -0
  366. package/dist/scenes/dictation/store.js +99 -0
  367. package/dist/scenes/look.d.ts +26 -0
  368. package/dist/scenes/look.js +1 -0
  369. package/dist/scenes/paint/painter.d.ts +84 -0
  370. package/dist/scenes/paint/painter.js +170 -0
  371. package/dist/scenes/paint/prompt.d.ts +23 -0
  372. package/dist/scenes/paint/prompt.js +36 -0
  373. package/dist/scenes/talk/en-words.d.ts +8 -0
  374. package/dist/scenes/talk/en-words.js +44 -0
  375. package/dist/scenes/talk/list.d.ts +44 -0
  376. package/dist/scenes/talk/list.js +88 -0
  377. package/dist/scenes/talk/store.d.ts +27 -0
  378. package/dist/scenes/talk/store.js +61 -0
  379. package/dist/scenes/talk/warmup.d.ts +16 -0
  380. package/dist/scenes/talk/warmup.js +39 -0
  381. package/dist/schema/activity.d.ts +149 -0
  382. package/dist/schema/activity.js +113 -0
  383. package/dist/schema/board.d.ts +200 -0
  384. package/dist/schema/board.js +42 -0
  385. package/dist/schema/config.d.ts +353 -80
  386. package/dist/schema/config.js +293 -76
  387. package/dist/schema/context-pack.d.ts +82 -13
  388. package/dist/schema/context-pack.js +97 -10
  389. package/dist/schema/conversation-files.d.ts +43 -0
  390. package/dist/schema/conversation-files.js +26 -0
  391. package/dist/schema/conversation.d.ts +459 -13
  392. package/dist/schema/conversation.js +148 -8
  393. package/dist/schema/events.d.ts +138 -0
  394. package/dist/schema/events.js +1 -0
  395. package/dist/schema/home.d.ts +46 -0
  396. package/dist/schema/home.js +30 -0
  397. package/dist/schema/index.d.ts +19 -4
  398. package/dist/schema/index.js +19 -4
  399. package/dist/schema/json-schema.d.ts +2 -0
  400. package/dist/schema/json-schema.js +23 -0
  401. package/dist/schema/kid-device.d.ts +20 -0
  402. package/dist/schema/kid-device.js +32 -0
  403. package/dist/schema/ledger.d.ts +9 -64
  404. package/dist/schema/ledger.js +7 -31
  405. package/dist/schema/memory.d.ts +73 -0
  406. package/dist/schema/memory.js +47 -0
  407. package/dist/schema/plan.d.ts +2 -2
  408. package/dist/schema/plan.js +2 -2
  409. package/dist/schema/sections.d.ts +32 -25
  410. package/dist/schema/sections.js +21 -22
  411. package/dist/schema/theme.d.ts +25 -0
  412. package/dist/schema/theme.js +26 -0
  413. package/dist/schema/timetable.d.ts +26 -0
  414. package/dist/schema/timetable.js +18 -0
  415. package/dist/schema/workspace.d.ts +41 -0
  416. package/dist/schema/workspace.js +9 -0
  417. package/dist/shared/errors.d.ts +8 -0
  418. package/dist/shared/errors.js +13 -0
  419. package/dist/shared/home.d.ts +2 -0
  420. package/dist/shared/home.js +16 -0
  421. package/dist/shared/human-notes.d.ts +5 -0
  422. package/dist/shared/human-notes.js +7 -0
  423. package/dist/shared/qianwen.d.ts +50 -0
  424. package/dist/shared/qianwen.js +109 -0
  425. package/dist/shared/time.d.ts +9 -0
  426. package/dist/shared/time.js +22 -0
  427. package/dist/shared/tokens.d.ts +18 -0
  428. package/dist/shared/tokens.js +11 -0
  429. package/dist/shared/wav.d.ts +10 -0
  430. package/dist/shared/wav.js +50 -0
  431. package/dist/stage/Assistant-Bold-ZDZZ6JHA.woff2 +0 -0
  432. package/dist/stage/Assistant-Medium-DZ25RZU3.woff2 +0 -0
  433. package/dist/stage/Assistant-Regular-PLF2XOGW.woff2 +0 -0
  434. package/dist/stage/Assistant-SemiBold-CZ5MX6FK.woff2 +0 -0
  435. package/dist/stage/chunk-226TNLQA.js +129 -0
  436. package/dist/stage/chunk-24LGQEKE.js +1 -0
  437. package/dist/stage/chunk-25XV6UY3.js +10 -0
  438. package/dist/stage/chunk-2AZI3NHJ.js +1 -0
  439. package/dist/stage/chunk-2BQZTTBE.js +1 -0
  440. package/dist/stage/chunk-2M7CGY3Y.js +11 -0
  441. package/dist/stage/chunk-2VR4WFQ7.js +10 -0
  442. package/dist/stage/chunk-2ZYXBUWG.js +9 -0
  443. package/dist/stage/chunk-32LAWMGY.js +1 -0
  444. package/dist/stage/chunk-3LEMTSOO.js +11 -0
  445. package/dist/stage/chunk-3QCKGZYE.js +32 -0
  446. package/dist/stage/chunk-44P66WFA.js +1 -0
  447. package/dist/stage/chunk-4AM6FRR6.js +7 -0
  448. package/dist/stage/chunk-4QDE4SUK.js +1 -0
  449. package/dist/stage/chunk-4QESHV3U.js +1 -0
  450. package/dist/stage/chunk-4SG5QPHB.js +2 -0
  451. package/dist/stage/chunk-4T4UVCOC.js +1 -0
  452. package/dist/stage/chunk-4WUEPPG3.js +34 -0
  453. package/dist/stage/chunk-4YCN6UZ5.js +99 -0
  454. package/dist/stage/chunk-5V7ZY2AP.js +1 -0
  455. package/dist/stage/chunk-5VS5Y2VJ.js +6 -0
  456. package/dist/stage/chunk-5W4NO2ZD.js +62 -0
  457. package/dist/stage/chunk-65CRNICM.js +1 -0
  458. package/dist/stage/chunk-66MULO7F.js +5 -0
  459. package/dist/stage/chunk-6COFQTBS.js +162 -0
  460. package/dist/stage/chunk-6VZG3M3I.js +8 -0
  461. package/dist/stage/chunk-7HVDH43T.js +1 -0
  462. package/dist/stage/chunk-7JLJN4EZ.js +8 -0
  463. package/dist/stage/chunk-7QDSP4LN.js +1 -0
  464. package/dist/stage/chunk-7R6OQAO3.js +1 -0
  465. package/dist/stage/chunk-7VTTHZKW.js +7 -0
  466. package/dist/stage/chunk-ATHR5KEN.js +10 -0
  467. package/dist/stage/chunk-B6R5LTP2.js +36 -0
  468. package/dist/stage/chunk-BD4WE264.js +1 -0
  469. package/dist/stage/chunk-BONANU47.js +206 -0
  470. package/dist/stage/chunk-BTVW7OFK.js +89 -0
  471. package/dist/stage/chunk-BUTJIDHG.js +8 -0
  472. package/dist/stage/chunk-C2IPYMML.js +84 -0
  473. package/dist/stage/chunk-C54FTPPV.js +9 -0
  474. package/dist/stage/chunk-C6LOUF2Z.js +90 -0
  475. package/dist/stage/chunk-CFF3PILO.js +339 -0
  476. package/dist/stage/chunk-CI2FQ2JY.js +9 -0
  477. package/dist/stage/chunk-CW5O4RV7.js +12 -0
  478. package/dist/stage/chunk-CYABNQYD.js +1 -0
  479. package/dist/stage/chunk-D7FFA4NS.js +15 -0
  480. package/dist/stage/chunk-DUNNXU6Z.js +8 -0
  481. package/dist/stage/chunk-E3E4Q6JF.js +6 -0
  482. package/dist/stage/chunk-EB3U3LH7.js +9 -0
  483. package/dist/stage/chunk-EGSZ736B.js +8 -0
  484. package/dist/stage/chunk-EOBXW5VQ.js +2 -0
  485. package/dist/stage/chunk-ERZC3B7Y.js +11 -0
  486. package/dist/stage/chunk-ESDOOBIH.js +11 -0
  487. package/dist/stage/chunk-EVU4QAL4.js +178 -0
  488. package/dist/stage/chunk-EVVZI2NY.js +39 -0
  489. package/dist/stage/chunk-FBKAZUKD.js +39 -0
  490. package/dist/stage/chunk-FDVKYQJN.js +1 -0
  491. package/dist/stage/chunk-FGPVYHVR.js +5 -0
  492. package/dist/stage/chunk-FHUD4AZC.js +1 -0
  493. package/dist/stage/chunk-FKUJ2DMY.js +96 -0
  494. package/dist/stage/chunk-FNZGVIJV.js +1 -0
  495. package/dist/stage/chunk-GBYSEGYM.js +78 -0
  496. package/dist/stage/chunk-GCO4TDHX.js +1 -0
  497. package/dist/stage/chunk-GKTML2LG.js +10 -0
  498. package/dist/stage/chunk-GMDIHHXQ.js +11 -0
  499. package/dist/stage/chunk-GOUNACI3.js +10 -0
  500. package/dist/stage/chunk-GXAYATPF.js +3 -0
  501. package/dist/stage/chunk-H2K2DDXV.js +8 -0
  502. package/dist/stage/chunk-H3UJI6ZY.js +13 -0
  503. package/dist/stage/chunk-H6PUGCME.js +7 -0
  504. package/dist/stage/chunk-HNBUIMIG.js +1 -0
  505. package/dist/stage/chunk-HRZY2BJQ.js +10 -0
  506. package/dist/stage/chunk-HSPJGALW.js +30 -0
  507. package/dist/stage/chunk-IBYORHIP.js +25 -0
  508. package/dist/stage/chunk-IHF4EWTY.js +1 -0
  509. package/dist/stage/chunk-ISBRPNKI.js +1 -0
  510. package/dist/stage/chunk-IZ3OI3C2.js +2 -0
  511. package/dist/stage/chunk-JEFZAC2R.js +1 -0
  512. package/dist/stage/chunk-JFIGRDPO.js +1 -0
  513. package/dist/stage/chunk-JFVYBOOC.js +9 -0
  514. package/dist/stage/chunk-JGD4TUTQ.js +1 -0
  515. package/dist/stage/chunk-JO4BEHDH.js +4 -0
  516. package/dist/stage/chunk-JOWBS42C.js +1 -0
  517. package/dist/stage/chunk-JP3TM2TG.js +1 -0
  518. package/dist/stage/chunk-JVK2C52O.js +1 -0
  519. package/dist/stage/chunk-K4I76XBX.js +14 -0
  520. package/dist/stage/chunk-KA6CZZ4M.js +1 -0
  521. package/dist/stage/chunk-KESSJ36M.js +1 -0
  522. package/dist/stage/chunk-LKATEVRU.js +1 -0
  523. package/dist/stage/chunk-LS4EJ2EI.js +1 -0
  524. package/dist/stage/chunk-LUKJQC2X.js +70 -0
  525. package/dist/stage/chunk-LWULR3SM.js +1 -0
  526. package/dist/stage/chunk-LWVRFMKX.js +2 -0
  527. package/dist/stage/chunk-LXC4ZBPZ.js +1 -0
  528. package/dist/stage/chunk-M2UP255H.js +1 -0
  529. package/dist/stage/chunk-MAPPXUZQ.js +231 -0
  530. package/dist/stage/chunk-MBMPW7Z5.js +1 -0
  531. package/dist/stage/chunk-MD3HMMTK.js +1 -0
  532. package/dist/stage/chunk-MLPCUIKR.js +17 -0
  533. package/dist/stage/chunk-MNQIRPDQ.js +8 -0
  534. package/dist/stage/chunk-MRG7MJVS.js +1 -0
  535. package/dist/stage/chunk-MU6EXW72.js +10 -0
  536. package/dist/stage/chunk-MVU2X6LU.js +4 -0
  537. package/dist/stage/chunk-N6UA5CZV.js +36 -0
  538. package/dist/stage/chunk-NLZIT2TJ.js +7 -0
  539. package/dist/stage/chunk-NOJR3J7M.js +1 -0
  540. package/dist/stage/chunk-NT7ARDOL.js +1 -0
  541. package/dist/stage/chunk-NWOGMPZH.js +1 -0
  542. package/dist/stage/chunk-NXE4KMG3.js +40 -0
  543. package/dist/stage/chunk-O4YCZXD2.js +257 -0
  544. package/dist/stage/chunk-OAJZ7HLK.js +1 -0
  545. package/dist/stage/chunk-OCFCFASO.js +1 -0
  546. package/dist/stage/chunk-ODGPG5RY.js +7 -0
  547. package/dist/stage/chunk-ODUEA52Q.js +3 -0
  548. package/dist/stage/chunk-OGDJ3FCI.js +1 -0
  549. package/dist/stage/chunk-OLDJ55TT.js +1 -0
  550. package/dist/stage/chunk-OOCL4ATI.js +2 -0
  551. package/dist/stage/chunk-OQEFDUDV.js +1 -0
  552. package/dist/stage/chunk-OQWVEWG7.js +4 -0
  553. package/dist/stage/chunk-OUIX6BGK.js +1 -0
  554. package/dist/stage/chunk-OV7OZYUO.js +7 -0
  555. package/dist/stage/chunk-PFGDY33O.js +1 -0
  556. package/dist/stage/chunk-PFJDUJB3.js +139 -0
  557. package/dist/stage/chunk-PGEW76ER.js +1 -0
  558. package/dist/stage/chunk-PP76TAQX.js +32 -0
  559. package/dist/stage/chunk-PTBOP4OT.js +2 -0
  560. package/dist/stage/chunk-PX2RVHCK.js +1 -0
  561. package/dist/stage/chunk-Q7K3PNAD.js +1 -0
  562. package/dist/stage/chunk-QDDPLZDB.js +1 -0
  563. package/dist/stage/chunk-QLGLZ77F.js +1 -0
  564. package/dist/stage/chunk-QOPFDFHI.js +1 -0
  565. package/dist/stage/chunk-QXT4KAEJ.js +1 -0
  566. package/dist/stage/chunk-R4YVZCIT.js +1 -0
  567. package/dist/stage/chunk-R6P6EHWA.js +62 -0
  568. package/dist/stage/chunk-RCH3OXBI.js +9 -0
  569. package/dist/stage/chunk-RHPE44I2.js +1 -0
  570. package/dist/stage/chunk-RJ2R4FVC.js +1 -0
  571. package/dist/stage/chunk-RJH2YVTD.js +1 -0
  572. package/dist/stage/chunk-RLWWW5OB.js +6 -0
  573. package/dist/stage/chunk-S3WO35Z7.js +120 -0
  574. package/dist/stage/chunk-S7ZGX6MW.js +1 -0
  575. package/dist/stage/chunk-SIAWX27B.js +1 -0
  576. package/dist/stage/chunk-SLG4X622.js +1 -0
  577. package/dist/stage/chunk-SLJRBC77.js +168 -0
  578. package/dist/stage/chunk-SRORWQJZ.js +1 -0
  579. package/dist/stage/chunk-STZTUIIF.js +2 -0
  580. package/dist/stage/chunk-SVQ6MWNV.js +9 -0
  581. package/dist/stage/chunk-TL3HLL2S.js +132 -0
  582. package/dist/stage/chunk-U3DOE6SF.js +24 -0
  583. package/dist/stage/chunk-UABQIZKW.js +6 -0
  584. package/dist/stage/chunk-UDK3R764.js +1 -0
  585. package/dist/stage/chunk-UFF4E54B.js +41 -0
  586. package/dist/stage/chunk-UFP5Q4AY.js +1 -0
  587. package/dist/stage/chunk-UMH2TSW2.js +72 -0
  588. package/dist/stage/chunk-UTASVNF5.js +10 -0
  589. package/dist/stage/chunk-UW7ML5ML.js +88 -0
  590. package/dist/stage/chunk-V3J7F6OP.js +1 -0
  591. package/dist/stage/chunk-VEHP5B5Q.js +5 -0
  592. package/dist/stage/chunk-VRXWB733.js +9 -0
  593. package/dist/stage/chunk-VVDHBBS5.js +5 -0
  594. package/dist/stage/chunk-VYFOH6FU.js +106 -0
  595. package/dist/stage/chunk-W3VZTLQS.js +3 -0
  596. package/dist/stage/chunk-W7WNRWTZ.js +8 -0
  597. package/dist/stage/chunk-WHUCV53C.js +1 -0
  598. package/dist/stage/chunk-WULMYHIF.js +1 -0
  599. package/dist/stage/chunk-X54EX7AW.js +9 -0
  600. package/dist/stage/chunk-X565ISZM.js +1 -0
  601. package/dist/stage/chunk-XGZMDECB.js +1 -0
  602. package/dist/stage/chunk-XHONC4RF.js +172 -0
  603. package/dist/stage/chunk-XIK4XQ6E.js +24 -0
  604. package/dist/stage/chunk-XJQQWFTE.js +1 -0
  605. package/dist/stage/chunk-XM4WOU3I.js +13 -0
  606. package/dist/stage/chunk-XM7Y5HP5.js +38 -0
  607. package/dist/stage/chunk-XNYYRGD5.js +292 -0
  608. package/dist/stage/chunk-XOYVR3SV.js +1 -0
  609. package/dist/stage/chunk-XQIW5HCE.js +1 -0
  610. package/dist/stage/chunk-YEWL7FUW.js +8 -0
  611. package/dist/stage/chunk-YI55PY3V.js +1 -0
  612. package/dist/stage/chunk-YM63HI6W.js +1 -0
  613. package/dist/stage/chunk-YNLGLU4P.js +9 -0
  614. package/dist/stage/chunk-YTNMNOWP.js +1 -0
  615. package/dist/stage/chunk-YV62XKTC.js +1 -0
  616. package/dist/stage/chunk-YVBA3QW6.js +1 -0
  617. package/dist/stage/chunk-Z2SY2HOC.js +1 -0
  618. package/dist/stage/chunk-ZBTCQEBK.js +10 -0
  619. package/dist/stage/chunk-ZCUFN74D.js +1 -0
  620. package/dist/stage/chunk-ZHOULXEJ.js +11 -0
  621. package/dist/stage/chunk-ZTRZIET2.js +1 -0
  622. package/dist/stage/index.html +11 -0
  623. package/dist/stage/stage.css +1 -0
  624. package/dist/stage/stage.js +1 -0
  625. package/dist/ui/dev/dev-page.d.ts +1 -0
  626. package/dist/ui/dev/dev-page.js +2248 -0
  627. package/dist/ui/dev/dev-theme.d.ts +6 -0
  628. package/dist/ui/dev/dev-theme.js +67 -0
  629. package/dist/ui/dev/qr-page.d.ts +8 -0
  630. package/dist/ui/dev/qr-page.js +61 -0
  631. package/dist/ui/dev/voice-gallery-page.d.ts +1 -0
  632. package/dist/ui/dev/voice-gallery-page.js +121 -0
  633. package/dist/ui/dev/voice-scenes.d.ts +21 -0
  634. package/dist/ui/dev/voice-scenes.js +30 -0
  635. package/dist/ui/dictation/en-box.d.ts +2 -0
  636. package/dist/ui/dictation/en-box.js +86 -0
  637. package/dist/ui/dictation/en-page.d.ts +1 -0
  638. package/dist/ui/dictation/en-page.js +484 -0
  639. package/dist/ui/dictation/page.d.ts +1 -0
  640. package/dist/ui/dictation/page.js +1084 -0
  641. package/dist/ui/dictation/parent-page.d.ts +1 -0
  642. package/dist/ui/dictation/parent-page.js +234 -0
  643. package/dist/ui/dictation/reel-mode.d.ts +1 -0
  644. package/dist/ui/dictation/reel-mode.js +87 -0
  645. package/dist/ui/dictation/reel-page.d.ts +1 -0
  646. package/dist/ui/dictation/reel-page.js +62 -0
  647. package/dist/ui/dictation/reel.d.ts +163 -0
  648. package/dist/ui/dictation/reel.js +436 -0
  649. package/dist/ui/dictation/ui.d.ts +44 -0
  650. package/dist/ui/dictation/ui.js +80 -0
  651. package/dist/ui/dictation/unlock.d.ts +7 -0
  652. package/dist/ui/dictation/unlock.js +16 -0
  653. package/dist/ui/kid/audio-client.d.ts +11 -0
  654. package/dist/ui/kid/audio-client.js +74 -0
  655. package/dist/ui/kid/board-mark-art.d.ts +37 -0
  656. package/dist/ui/kid/board-mark-art.js +5 -0
  657. package/dist/ui/kid/board-mark.d.ts +24 -0
  658. package/dist/ui/kid/board-mark.js +58 -0
  659. package/dist/ui/kid/kid-log.d.ts +15 -0
  660. package/dist/ui/kid/kid-log.js +87 -0
  661. package/dist/ui/kid/kid-nav.d.ts +11 -0
  662. package/dist/ui/kid/kid-nav.js +22 -0
  663. package/dist/ui/kid/kid-page.d.ts +9 -0
  664. package/dist/ui/kid/kid-page.js +3719 -0
  665. package/dist/ui/kid/letters.d.ts +26 -0
  666. package/dist/ui/kid/letters.js +51 -0
  667. package/dist/ui/kid/photo-edit.d.ts +83 -0
  668. package/dist/ui/kid/photo-edit.js +106 -0
  669. package/dist/ui/kid/photo-ui.d.ts +23 -0
  670. package/dist/ui/kid/photo-ui.js +60 -0
  671. package/dist/ui/kid/reel.d.ts +419 -0
  672. package/dist/ui/kid/reel.js +648 -0
  673. package/dist/ui/kid/tianzige.d.ts +8 -0
  674. package/dist/ui/kid/tianzige.js +45 -0
  675. package/dist/ui/kid/tutor-face.d.ts +35 -0
  676. package/dist/ui/kid/tutor-face.js +84 -0
  677. package/dist/ui/kid/voice-ui.d.ts +70 -0
  678. package/dist/ui/kid/voice-ui.js +316 -0
  679. package/dist/ui/kid/voice-view.d.ts +71 -0
  680. package/dist/ui/kid/voice-view.js +75 -0
  681. package/dist/ui/kid/word-draw.d.ts +2 -0
  682. package/dist/ui/kid/word-draw.js +107 -0
  683. package/dist/ui/kid/word-emoji.d.ts +10 -0
  684. package/dist/ui/kid/word-emoji.js +66 -0
  685. package/dist/ui/kid/word-layout.d.ts +25 -0
  686. package/dist/ui/kid/word-layout.js +29 -0
  687. package/dist/ui/parent/parent-home-page.d.ts +1 -0
  688. package/dist/ui/parent/parent-home-page.js +414 -0
  689. package/dist/ui/parent/parent-page.d.ts +2 -0
  690. package/dist/ui/parent/parent-page.js +507 -0
  691. package/dist/ui/shared/brand.d.ts +36 -0
  692. package/dist/ui/shared/brand.js +51 -0
  693. package/dist/ui/shared/favicon.d.ts +12 -0
  694. package/dist/ui/shared/favicon.js +96 -0
  695. package/dist/ui/shared/icon.d.ts +9 -0
  696. package/dist/ui/shared/icon.js +35 -0
  697. package/dist/ui/shared/inline-lib.d.ts +1 -0
  698. package/dist/ui/shared/inline-lib.js +28 -0
  699. package/dist/ui/shared/logo.d.ts +31 -0
  700. package/dist/ui/shared/logo.js +43 -0
  701. package/dist/ui/shared/page-dom.d.ts +12 -0
  702. package/dist/ui/shared/page-dom.js +36 -0
  703. package/dist/ui/shared/png.d.ts +1 -0
  704. package/dist/ui/shared/png.js +45 -0
  705. package/dist/ui/shared/qr-svg.d.ts +3 -0
  706. package/dist/ui/shared/qr-svg.js +32 -0
  707. package/dist/ui/shared/qr.d.ts +14 -0
  708. package/dist/ui/shared/qr.js +281 -0
  709. package/dist/ui/shared/reel-dock.d.ts +22 -0
  710. package/dist/ui/shared/reel-dock.js +365 -0
  711. package/dist/ui/shared/tutor-color.d.ts +15 -0
  712. package/dist/ui/shared/tutor-color.js +47 -0
  713. package/dist/ui/talk/page.d.ts +6 -0
  714. package/dist/ui/talk/page.js +294 -0
  715. package/grades/grade-2/README.md +11 -0
  716. package/grades/grade-2/VALIDATION.md +41 -0
  717. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273.md +157 -0
  718. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273./344/276/213/345/255/220.md +78 -0
  719. package/grades/grade-2/agents/chinese-tutor/activities//344/276/213/345/255/220/345/233/276//345/200/237/344/274/236.jpg +0 -0
  720. package/grades/grade-2/agents/chinese-tutor/activities//344/276/213/345/255/220/345/233/276//345/260/217/347/214/264/346/221/230/346/241/203.jpg +0 -0
  721. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235.md +64 -0
  722. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235./344/276/213/345/255/220.md +31 -0
  723. package/grades/grade-2/agents/chinese-tutor/activities//345/220/254/345/206/231.md +48 -0
  724. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240.md +79 -0
  725. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  726. package/grades/grade-2/agents/chinese-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  727. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271.md +81 -0
  728. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  729. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235.md +94 -0
  730. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235./344/276/213/345/255/220.md +63 -0
  731. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240.md +82 -0
  732. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  733. package/grades/grade-2/agents/chinese-tutor.md +59 -0
  734. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276.md +149 -0
  735. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276./344/276/213/345/255/220.md +13 -0
  736. package/grades/grade-2/agents/english-tutor/activities//345/220/254/345/206/231.md +47 -0
  737. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240.md +78 -0
  738. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  739. package/grades/grade-2/agents/english-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  740. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271.md +80 -0
  741. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  742. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240.md +86 -0
  743. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  744. package/grades/grade-2/agents/english-tutor.md +57 -0
  745. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240.md +78 -0
  746. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  747. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202.md +56 -0
  748. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202./344/276/213/345/255/220.md +52 -0
  749. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271.md +80 -0
  750. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  751. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240.md +81 -0
  752. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  753. package/grades/grade-2/agents/math-tutor.md +51 -0
  754. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/index.json +44 -0
  755. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-1.mp3 +0 -0
  756. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-2.mp3 +0 -0
  757. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-3.mp3 +0 -0
  758. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-4.mp3 +0 -0
  759. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-5.mp3 +0 -0
  760. package/grades/grade-2/examples/2026-10-27-pingjunfen/bake.json +1 -0
  761. package/grades/grade-2/examples/2026-10-27-pingjunfen/manifest.json +63 -0
  762. package/grades/grade-2/examples/2026-10-27-pingjunfen/scene.json +247 -0
  763. package/grades/grade-2/examples/2026-10-27-pingjunfen.md +40 -0
  764. package/grades/grade-2/examples/2026-10-27-pingjunfen.ts +26 -0
  765. package/grades/grade-2/examples//345/271/263/345/235/207/345/210/206./344/276/213/345/255/220.md +24 -0
  766. package/grades/grade-2/examples//346/225/260/345/255/246/345/271/263/345/235/207/345/210/206.md +42 -0
  767. package/grades/grade-2/validation/2026-10-27.json +4410 -0
  768. package/package.json +32 -12
  769. package/skills/chalk-cli/SKILL.md +62 -0
  770. package/skills/chalk-scene/SKILL.md +91 -0
  771. package/skills/chalk-teaching/SKILL.md +82 -0
  772. package/skills/chalk-teaching/models//344/272/244/351/224/231/346/225/260/345/210/227/345/210/206/350/241/214.md +8 -0
  773. package/skills/chalk-teaching/models//345/207/221/345/215/201.md +7 -0
  774. package/skills/chalk-teaching/models//345/221/250/346/234/237/350/247/204/345/276/213.md +6 -0
  775. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/345/242/236/345/207/217.md +6 -0
  776. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/346/257/224/345/244/232/345/260/221-/346/261/202/345/244/247/346/225/260/346/261/202/345/260/217/346/225/260.md +7 -0
  777. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/346/257/224/345/244/232/345/260/221-/346/261/202/345/267/256.md +6 -0
  778. package/skills/chalk-teaching/models//345/260/217/346/243/222/350/277/233/344/275/215/345/212/240.md +7 -0
  779. package/skills/chalk-teaching/models//345/260/217/346/243/222/351/200/200/344/275/215/345/207/217.md +6 -0
  780. package/skills/chalk-teaching/models//346/216/222/351/230/237/347/202/271/351/230/265.md +7 -0
  781. package/skills/chalk-teaching/models//346/227/266/351/227/264/346/225/260/350/275/264.md +6 -0
  782. package/skills/chalk-teaching/models//346/245/274/345/261/202/351/227/264/351/232/224/345/233/276.md +7 -0
  783. package/skills/chalk-teaching/models//347/240/264/345/215/201.md +7 -0
  784. package/skills/chalk-teaching/models//347/253/226/345/274/217/351/200/200/344/275/215.md +6 -0
  785. package/skills/chalk-teaching/models//347/272/277/346/256/265/345/233/276.md +7 -0
  786. package/skills/chalk-teaching/models-index.md +24 -0
  787. package/skills/chalk-teaching/references//350/256/262/350/247/243/346/250/241/346/235/277/344/270/211/346/241/243.md +32 -0
  788. package/skills/chalk-teaching/references//350/257/264/346/230/216/346/226/207/344/273/266.md +102 -0
  789. package/skills/chalk-verify/SKILL.md +57 -0
  790. package/skills/chalk-verify/references//350/257/204/345/210/244/346/240/207/345/207/206.md +69 -0
  791. package/skills/cotutor-analyze/SKILL.md +106 -0
  792. package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +31 -0
  793. package/skills/cotutor-board/SKILL.md +373 -0
  794. package/skills/cotutor-board/references/README.md +38 -0
  795. package/skills/cotutor-board/references/canvas.md +68 -0
  796. package/skills/cotutor-board/references/choice.md +55 -0
  797. package/skills/cotutor-board/references/code.md +46 -0
  798. package/skills/cotutor-board/references/image.md +52 -0
  799. package/skills/cotutor-board/references/lecture.md +69 -0
  800. package/skills/cotutor-board/references/paint.md +77 -0
  801. package/skills/cotutor-board/references/photo.md +61 -0
  802. package/skills/cotutor-board/references/read.md +51 -0
  803. package/skills/cotutor-board/references/text.md +69 -0
  804. package/skills/cotutor-board/references/tianzige.md +78 -0
  805. package/skills/cotutor-board/references/word.md +91 -0
  806. package/skills/cotutor-home/SKILL.md +169 -0
  807. package/skills/cotutor-home/references/dictation.md +97 -0
  808. package/skills/cotutor-home/references/tutor.md +148 -0
  809. package/skills/cotutor-home/references//345/221/275/344/273/244.md +21 -0
  810. package/skills/cotutor-home/references//351/246/226/351/241/265/350/257/255/346/263/225.md +142 -0
  811. package/skills/cotutor-tune/SKILL.md +147 -0
  812. package/skills/cotutor-tune/references//345/255/227/346/256/265.md +50 -0
  813. package/skills/cotutor-tutor/SKILL.md +261 -0
  814. package/skills/cotutor-tutor/references//344/270/212/344/270/213/346/226/207/345/214/205.md +78 -0
  815. package/themes/default/kid.css +86 -0
  816. package/themes/default/theme.json +26 -0
  817. package/agents/chinese-teacher.md +0 -19
  818. package/agents/homework-aide.md +0 -17
  819. package/agents/math-teacher.md +0 -19
  820. package/agents/planner.md +0 -18
  821. package/agents/reading-teacher.md +0 -19
  822. package/dist/cli/doctor.d.ts +0 -19
  823. package/dist/cli/doctor.js +0 -190
  824. package/dist/cli/init.js +0 -114
  825. package/dist/cli/main.js +0 -123
  826. package/dist/cli/serve.d.ts +0 -19
  827. package/dist/cli/serve.js +0 -22
  828. package/dist/cli/skeleton.d.ts +0 -21
  829. package/dist/cli/skeleton.js +0 -82
  830. package/dist/cli/workspace.d.ts +0 -61
  831. package/dist/lib/agent-file.d.ts +0 -10
  832. package/dist/lib/agent-file.js +0 -16
  833. package/dist/lib/context-pack.js +0 -46
  834. package/dist/lib/conversation.d.ts +0 -28
  835. package/dist/lib/conversation.js +0 -44
  836. package/dist/lib/kid-view.d.ts +0 -26
  837. package/dist/lib/kid-view.js +0 -38
  838. package/dist/lib/ledger.d.ts +0 -21
  839. package/dist/lib/sections.d.ts +0 -12
  840. package/dist/lib/sections.js +0 -151
  841. package/dist/lib/transcript.d.ts +0 -36
  842. package/dist/lib/transcript.js +0 -95
  843. package/dist/server/app.d.ts +0 -13
  844. package/dist/server/app.js +0 -45
  845. /package/dist/{cli → app/cli}/main.d.ts +0 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * 画板:孩子的笔迹怎么数(各色几笔、大致在哪、画了多久),边画边聊时嘴什么时候主动说一句、说哪个颜色。纯函数。
3
+ * 剥类型内联进孩子端页面(同 runtime/delivery/player.ts),名字都带 canvas 前缀;服务端的画板卡 describe、纸交画时的摘要也用它。
4
+ * 改「什么时候说」先改的规矩,再改 tests/canvas-chat.test.ts,最后改这里(CANVAS_CHAT 是调参表)。
5
+ */
6
+ /** 舞台的三支笔(src/ui/stage/canvas.tsx 的 INK_COLORS)叫什么;别的颜色(以后加的)叫「别的颜色」 */
7
+ export declare const CANVAS_COLOR_NAMES: Readonly<Record<string, string>>;
8
+ /** 一笔:颜色名、画完的时刻(excalidraw 元素的 updated,毫秒)、外框(画布坐标) */
9
+ export interface CanvasStroke {
10
+ color: string;
11
+ at: number;
12
+ x0: number;
13
+ y0: number;
14
+ x1: number;
15
+ y1: number;
16
+ }
17
+ /** 一种颜色:几笔、在整张画里大致哪儿(上边偏右、中间、铺满大半张) */
18
+ export interface CanvasColor {
19
+ name: string;
20
+ strokes: number;
21
+ where: string;
22
+ }
23
+ export interface CanvasSummary {
24
+ strokes: number;
25
+ /** 笔多的在前 */
26
+ colors: CanvasColor[];
27
+ /** 第一笔、最后一笔画完的时刻;没画是 null */
28
+ firstAt: number | null;
29
+ lastAt: number | null;
30
+ }
31
+ /** 笔迹(舞台存回来的 excalidraw 元素,customData.layer = 'ink')→ 一笔一行;删掉的、不是线条的不算 */
32
+ export declare function canvasStrokes(ink: readonly Record<string, unknown>[]): CanvasStroke[];
33
+ /** 整张画的摘要:几笔、各颜色几笔在哪、第一笔与最后一笔的时刻 */
34
+ export declare function canvasSummary(strokes: readonly CanvasStroke[]): CanvasSummary;
35
+ /** 「红 40 笔、蓝 51 笔」;只有一种颜色就只写几笔 */
36
+ export declare function canvasColorsText(s: CanvasSummary): string;
37
+ /** 画了多久(第一笔到最后一笔,加上清空前画的那几版):不到 1 分钟写「不到 1 分钟」 */
38
+ export declare function canvasMinutesText(ms: number): string;
39
+ /**
40
+ * 边画边聊的规矩(10-22 :先这样,跑一周再调)。毫秒。
41
+ * 换色:一种颜色从上一句到现在新画了 ≥ colorStrokes 笔、孩子换了颜色 → 说刚画完的那种;
42
+ * 久停:这一张 ≥ pauseStrokes 笔以后停笔 ≥ pauseMs → 说整张(上一句之后又画过才算);
43
+ * 不说:点开后 openQuietMs 内、上一笔不到 drawingMs(正在画)、清空后 clearQuietMs 内、孩子按头像说过 kidQuietMs 内、离上一句不到 gapMs、一张已经说了 maxLines 句;
44
+ * 不追:上一句问了没回 → 这句只说不问;连着 stopUnanswered 句没回 → 这一张不说了(他画得入神)
45
+ */
46
+ export declare const CANVAS_CHAT: {
47
+ colorStrokes: number;
48
+ pauseStrokes: number;
49
+ pauseMs: number;
50
+ openQuietMs: number;
51
+ drawingMs: number;
52
+ clearQuietMs: number;
53
+ kidQuietMs: number;
54
+ gapMs: number;
55
+ maxLines: number;
56
+ stopUnanswered: number;
57
+ };
58
+ /** 嘴主动说过的一句:时刻、说的哪种颜色(null = 整张)、问没问、孩子回了没有、那时各颜色几笔 */
59
+ export interface CanvasChatLine {
60
+ at: number;
61
+ color: string | null;
62
+ ask: boolean;
63
+ answered: boolean;
64
+ counts: Record<string, number>;
65
+ strokes: number;
66
+ }
67
+ /** 这一张纸(清空算新的一张)上边画边聊到哪了;kidAt = 孩子最近一次按头像说话 */
68
+ export interface CanvasChatState {
69
+ openedAt: number;
70
+ clearedAt: number | null;
71
+ kidAt: number | null;
72
+ lines: CanvasChatLine[];
73
+ }
74
+ /** 要不要说:say = false 带为什么(测试、录像看);说的话带说哪种颜色(null = 整张)、问不问 */
75
+ export type CanvasChatDue = {
76
+ say: false;
77
+ why: string;
78
+ } | {
79
+ say: true;
80
+ color: string | null;
81
+ ask: boolean;
82
+ why: 'color' | 'pause';
83
+ };
84
+ export declare function canvasChatInit(now: number): CanvasChatState;
85
+ /** 清空了:新的一张,计数重来 */
86
+ export declare function canvasChatCleared(st: CanvasChatState, now: number): CanvasChatState;
87
+ /** 孩子按着头像说了话(边画边聊):最近一句算回了;嘴刚接住他,一会儿内不再主动说 */
88
+ export declare function canvasChatAnswered(st: CanvasChatState, now: number): CanvasChatState;
89
+ /**
90
+ * 这一刻要不要说。busy = 孩子按着说话、嘴或卡在出声、脑在写(页面凑);strokes = 这一刻的笔(画完的时刻是 at)。
91
+ * 换色比久停先:刚画完的那种颜色具体,好问
92
+ */
93
+ export declare function canvasChatDue(st: CanvasChatState, now: number, strokes: readonly CanvasStroke[], busy: boolean): CanvasChatDue;
94
+ /** 说了:记下这一句(那时各颜色几笔,下次算「新画了几笔」) */
95
+ export declare function canvasChatSaid(st: CanvasChatState, now: number, due: Extract<CanvasChatDue, {
96
+ say: true;
97
+ }>, strokes: readonly CanvasStroke[]): CanvasChatState;
@@ -0,0 +1,175 @@
1
+ /**
2
+ * 画板:孩子的笔迹怎么数(各色几笔、大致在哪、画了多久),边画边聊时嘴什么时候主动说一句、说哪个颜色。纯函数。
3
+ * 剥类型内联进孩子端页面(同 runtime/delivery/player.ts),名字都带 canvas 前缀;服务端的画板卡 describe、纸交画时的摘要也用它。
4
+ * 改「什么时候说」先改的规矩,再改 tests/canvas-chat.test.ts,最后改这里(CANVAS_CHAT 是调参表)。
5
+ */
6
+ /** 舞台的三支笔(src/ui/stage/canvas.tsx 的 INK_COLORS)叫什么;别的颜色(以后加的)叫「别的颜色」 */
7
+ export const CANVAS_COLOR_NAMES = { '#2b2b2b': '黑', '#d9482b': '红', '#2f6fd6': '蓝' };
8
+ const canvasNum = (v, d = 0) => (typeof v === 'number' && Number.isFinite(v) ? v : d);
9
+ /** 笔迹(舞台存回来的 excalidraw 元素,customData.layer = 'ink')→ 一笔一行;删掉的、不是线条的不算 */
10
+ export function canvasStrokes(ink) {
11
+ const out = [];
12
+ for (const el of ink) {
13
+ if (!el || el.isDeleted === true)
14
+ continue;
15
+ const x = canvasNum(el.x), y = canvasNum(el.y);
16
+ const pts = Array.isArray(el.points) ? el.points.filter((p) => Array.isArray(p) && p.length >= 2 && typeof p[0] === 'number' && typeof p[1] === 'number') : [];
17
+ let x0 = x, y0 = y, x1 = x + canvasNum(el.width), y1 = y + canvasNum(el.height);
18
+ if (pts.length) {
19
+ x0 = Infinity;
20
+ y0 = Infinity;
21
+ x1 = -Infinity;
22
+ y1 = -Infinity;
23
+ for (const p of pts) {
24
+ x0 = Math.min(x0, x + p[0]);
25
+ y0 = Math.min(y0, y + p[1]);
26
+ x1 = Math.max(x1, x + p[0]);
27
+ y1 = Math.max(y1, y + p[1]);
28
+ }
29
+ }
30
+ const raw = typeof el.strokeColor === 'string' ? el.strokeColor.toLowerCase() : '';
31
+ out.push({ color: CANVAS_COLOR_NAMES[raw] ?? '别的颜色', at: canvasNum(el.updated), x0, y0, x1, y1 });
32
+ }
33
+ return out;
34
+ }
35
+ /** 一块外框在整张画的外框里大致哪儿:占了一半以上 = 铺满大半张;不然按中心落在九宫格哪格 */
36
+ function canvasWhere(b, all) {
37
+ const W = Math.max(1, all.x1 - all.x0), H = Math.max(1, all.y1 - all.y0);
38
+ const area = (Math.max(0, b.x1 - b.x0) * Math.max(0, b.y1 - b.y0)) / (W * H);
39
+ if (area >= 0.5)
40
+ return '铺满大半张';
41
+ const cx = ((b.x0 + b.x1) / 2 - all.x0) / W, cy = ((b.y0 + b.y1) / 2 - all.y0) / H;
42
+ const v = cy < 1 / 3 ? '上边' : cy > 2 / 3 ? '下边' : '中间';
43
+ const hz = cx < 1 / 3 ? '偏左' : cx > 2 / 3 ? '偏右' : '';
44
+ return v === '中间' && hz ? (hz === '偏左' ? '左边' : '右边') : v + hz;
45
+ }
46
+ /** 整张画的摘要:几笔、各颜色几笔在哪、第一笔与最后一笔的时刻 */
47
+ export function canvasSummary(strokes) {
48
+ if (!strokes.length)
49
+ return { strokes: 0, colors: [], firstAt: null, lastAt: null };
50
+ const all = { x0: Infinity, y0: Infinity, x1: -Infinity, y1: -Infinity };
51
+ const by = new Map();
52
+ let firstAt = Infinity, lastAt = -Infinity;
53
+ strokes.forEach((s, i) => {
54
+ all.x0 = Math.min(all.x0, s.x0);
55
+ all.y0 = Math.min(all.y0, s.y0);
56
+ all.x1 = Math.max(all.x1, s.x1);
57
+ all.y1 = Math.max(all.y1, s.y1);
58
+ if (s.at > 0) {
59
+ firstAt = Math.min(firstAt, s.at);
60
+ lastAt = Math.max(lastAt, s.at);
61
+ }
62
+ const c = by.get(s.color) ?? { n: 0, first: i, b: { x0: Infinity, y0: Infinity, x1: -Infinity, y1: -Infinity } };
63
+ c.n++;
64
+ c.b = { x0: Math.min(c.b.x0, s.x0), y0: Math.min(c.b.y0, s.y0), x1: Math.max(c.b.x1, s.x1), y1: Math.max(c.b.y1, s.y1) };
65
+ by.set(s.color, c);
66
+ });
67
+ const colors = [...by.entries()].sort((a, b) => b[1].n - a[1].n || a[1].first - b[1].first).map(([name, c]) => ({ name, strokes: c.n, where: canvasWhere(c.b, all) }));
68
+ return { strokes: strokes.length, colors, firstAt: Number.isFinite(firstAt) ? firstAt : null, lastAt: Number.isFinite(lastAt) ? lastAt : null };
69
+ }
70
+ /** 「红 40 笔、蓝 51 笔」;只有一种颜色就只写几笔 */
71
+ export function canvasColorsText(s) {
72
+ if (!s.strokes)
73
+ return '还没画';
74
+ if (s.colors.length <= 1)
75
+ return `${s.strokes} 笔${s.colors[0] ? `(${s.colors[0].name})` : ''}`;
76
+ return s.colors.map((c) => `${c.name} ${c.strokes} 笔`).join('、');
77
+ }
78
+ /** 画了多久(第一笔到最后一笔,加上清空前画的那几版):不到 1 分钟写「不到 1 分钟」 */
79
+ export function canvasMinutesText(ms) {
80
+ if (!(ms >= 60_000))
81
+ return '不到 1 分钟';
82
+ return `约 ${Math.round(ms / 60_000)} 分钟`;
83
+ }
84
+ /**
85
+ * 边画边聊的规矩(10-22 :先这样,跑一周再调)。毫秒。
86
+ * 换色:一种颜色从上一句到现在新画了 ≥ colorStrokes 笔、孩子换了颜色 → 说刚画完的那种;
87
+ * 久停:这一张 ≥ pauseStrokes 笔以后停笔 ≥ pauseMs → 说整张(上一句之后又画过才算);
88
+ * 不说:点开后 openQuietMs 内、上一笔不到 drawingMs(正在画)、清空后 clearQuietMs 内、孩子按头像说过 kidQuietMs 内、离上一句不到 gapMs、一张已经说了 maxLines 句;
89
+ * 不追:上一句问了没回 → 这句只说不问;连着 stopUnanswered 句没回 → 这一张不说了(他画得入神)
90
+ */
91
+ export const CANVAS_CHAT = {
92
+ colorStrokes: 5,
93
+ pauseStrokes: 10,
94
+ pauseMs: 12_000,
95
+ openQuietMs: 20_000,
96
+ drawingMs: 2_000,
97
+ clearQuietMs: 30_000,
98
+ kidQuietMs: 15_000,
99
+ gapMs: 45_000,
100
+ maxLines: 4,
101
+ stopUnanswered: 2,
102
+ };
103
+ export function canvasChatInit(now) {
104
+ return { openedAt: now, clearedAt: null, kidAt: null, lines: [] };
105
+ }
106
+ /** 清空了:新的一张,计数重来 */
107
+ export function canvasChatCleared(st, now) {
108
+ return { ...st, clearedAt: now, lines: [] };
109
+ }
110
+ /** 孩子按着头像说了话(边画边聊):最近一句算回了;嘴刚接住他,一会儿内不再主动说 */
111
+ export function canvasChatAnswered(st, now) {
112
+ const lines = st.lines.slice();
113
+ if (lines.length)
114
+ lines[lines.length - 1] = { ...lines[lines.length - 1], answered: true };
115
+ return { ...st, kidAt: now, lines };
116
+ }
117
+ const canvasCounts = (strokes) => {
118
+ const c = {};
119
+ for (const s of strokes)
120
+ c[s.color] = (c[s.color] ?? 0) + 1;
121
+ return c;
122
+ };
123
+ /**
124
+ * 这一刻要不要说。busy = 孩子按着说话、嘴或卡在出声、脑在写(页面凑);strokes = 这一刻的笔(画完的时刻是 at)。
125
+ * 换色比久停先:刚画完的那种颜色具体,好问
126
+ */
127
+ export function canvasChatDue(st, now, strokes, busy) {
128
+ const T = CANVAS_CHAT;
129
+ if (busy)
130
+ return { say: false, why: 'busy' };
131
+ if (now - st.openedAt < T.openQuietMs)
132
+ return { say: false, why: 'opened' };
133
+ if (st.clearedAt !== null && now - st.clearedAt < T.clearQuietMs)
134
+ return { say: false, why: 'cleared' };
135
+ if (st.kidAt !== null && now - st.kidAt < T.kidQuietMs)
136
+ return { say: false, why: 'kid' };
137
+ if (!strokes.length)
138
+ return { say: false, why: 'empty' };
139
+ const lines = st.lines;
140
+ if (lines.length >= T.maxLines)
141
+ return { say: false, why: 'max' };
142
+ const tail = lines.slice(-T.stopUnanswered);
143
+ if (tail.length === T.stopUnanswered && tail.every((l) => !l.answered))
144
+ return { say: false, why: 'unanswered' };
145
+ const last = lines[lines.length - 1];
146
+ if (last && now - last.at < T.gapMs)
147
+ return { say: false, why: 'gap' };
148
+ const lastAt = strokes.reduce((m, s) => Math.max(m, s.at), 0);
149
+ if (now - lastAt < T.drawingMs)
150
+ return { say: false, why: 'drawing' };
151
+ const ask = !(last && last.ask && !last.answered);
152
+ // 换色:按画完的先后排,最后一段同色之前那段的颜色;它从上一句到现在新画了够多
153
+ const seq = strokes.slice().sort((a, b) => a.at - b.at);
154
+ const now0 = seq[seq.length - 1].color;
155
+ let k = seq.length - 1;
156
+ while (k >= 0 && seq[k].color === now0)
157
+ k--;
158
+ const counts = canvasCounts(strokes);
159
+ if (k >= 0) {
160
+ const prev = seq[k].color;
161
+ const fresh = (counts[prev] ?? 0) - (last?.counts[prev] ?? 0);
162
+ if (fresh >= T.colorStrokes)
163
+ return { say: true, color: prev, ask, why: 'color' };
164
+ }
165
+ // 还没换色、这一种已经画了很多(一整张都是一种颜色):停笔够久也说它
166
+ if (strokes.length >= T.pauseStrokes && now - lastAt >= T.pauseMs && (!last || lastAt > last.at)) {
167
+ const only = Object.keys(counts).length === 1 ? now0 : null;
168
+ return { say: true, color: only, ask, why: 'pause' };
169
+ }
170
+ return { say: false, why: 'wait' };
171
+ }
172
+ /** 说了:记下这一句(那时各颜色几笔,下次算「新画了几笔」) */
173
+ export function canvasChatSaid(st, now, due, strokes) {
174
+ return { ...st, lines: [...st.lines, { at: now, color: due.color, ask: due.ask, answered: false, counts: canvasCounts(strokes), strokes: strokes.length }] };
175
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 按卡裁的段落(《卡片协议.md》「谁拿到哪些卡」):板书写法的手写部分(cards/板书怎么写.md)与守则(cotutor-tutor)里,
3
+ * 只对某几种卡有用的段落用 `{{有 x y}}` … `{{/有}}` 包起来,递给某位老师时按他的卡留或去。纯函数,不读文件。
4
+ * activity 文件的「老师怎么带」也用它,名字还可以是参数(填了才留,src/runtime/activity.ts)。
5
+ */
6
+ /** 守卫行;名字是卡的种类(英文小写),或 activity 的参数名(汉字,src/runtime/activity.ts) */
7
+ export declare const GUARD_OPEN: RegExp;
8
+ export declare const GUARD_CLOSE: RegExp;
9
+ /**
10
+ * 按卡裁的段落:`{{有 x y}}` 到 `{{/有}}` 之间的行,x、y 都在 kinds 里才留;守卫行本身不留,能套。
11
+ * 删掉一段留下的连续空行并成一行。守卫不配对就抛(gen:skills 与测试先红)。
12
+ */
13
+ export declare function applyCardGuards(text: string, kinds: readonly string[]): string;
14
+ /** 同上,「有没有」由 has 定:activity 递给老师时,名字是参数就看填没填,是卡就看这个话题有没有 */
15
+ export declare function applyGuards(text: string, has: (name: string) => boolean): string;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 按卡裁的段落(《卡片协议.md》「谁拿到哪些卡」):板书写法的手写部分(cards/板书怎么写.md)与守则(cotutor-tutor)里,
3
+ * 只对某几种卡有用的段落用 `{{有 x y}}` … `{{/有}}` 包起来,递给某位老师时按他的卡留或去。纯函数,不读文件。
4
+ * activity 文件的「老师怎么带」也用它,名字还可以是参数(填了才留,src/runtime/activity.ts)。
5
+ */
6
+ /** 守卫行;名字是卡的种类(英文小写),或 activity 的参数名(汉字,src/runtime/activity.ts) */
7
+ export const GUARD_OPEN = /^\{\{有((?:\s+[^\s{}]+)+)\}\}\s*$/;
8
+ export const GUARD_CLOSE = /^\{\{\/有\}\}\s*$/;
9
+ /**
10
+ * 按卡裁的段落:`{{有 x y}}` 到 `{{/有}}` 之间的行,x、y 都在 kinds 里才留;守卫行本身不留,能套。
11
+ * 删掉一段留下的连续空行并成一行。守卫不配对就抛(gen:skills 与测试先红)。
12
+ */
13
+ export function applyCardGuards(text, kinds) {
14
+ return applyGuards(text, (name) => kinds.includes(name));
15
+ }
16
+ /** 同上,「有没有」由 has 定:activity 递给老师时,名字是参数就看填没填,是卡就看这个话题有没有 */
17
+ export function applyGuards(text, has) {
18
+ const keep = [];
19
+ const out = [];
20
+ for (const line of text.split('\n')) {
21
+ const open = GUARD_OPEN.exec(line);
22
+ if (open) {
23
+ keep.push(open[1].trim().split(/\s+/).every(has));
24
+ continue;
25
+ }
26
+ if (GUARD_CLOSE.test(line)) {
27
+ if (!keep.length)
28
+ throw new Error('{{/有}} 多了一个');
29
+ keep.pop();
30
+ continue;
31
+ }
32
+ if (keep.every(Boolean))
33
+ out.push(line);
34
+ }
35
+ if (keep.length)
36
+ throw new Error('{{有 …}} 没有配对的 {{/有}}');
37
+ return out.join('\n').replace(/\n{3,}/g, '\n\n');
38
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 画板卡:孩子在上面画。底图四种——课包 id(整幅终帧做底层)、行内小骨架 JSON、一张图(孩子拍的作业
3
+ * captures/… 或别的 workspace 里的图片,R5:在自己的作业照片上圈错题、写答案)、空白 + 题目;
4
+ * 舞台是舞台包里的 excalidraw 编辑器(底层锁定,孩子的笔打 customData.layer = 'ink');「给老师看」→ 导出 png 存 .cards/<n>.png,
5
+ * 状态存 ink 元素;清空前那一版存一张图(cleared);describe 给笔数、各颜色几笔、画了多久、清空过几次与图的路径,
6
+ * 老师 Read 看图(进上下文包时 runner 换成绝对路径、这轮带只读工具;看不了图就靠笔数)。
7
+ */
8
+ import { z } from 'zod';
9
+ import { type CardKind } from './kind.ts';
10
+ export declare const CanvasPropsSchema: z.ZodObject<{
11
+ base: z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
12
+ bundle: z.ZodString;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ skeletons: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
15
+ }, z.core.$strip>, z.ZodObject<{
16
+ image: z.ZodString;
17
+ }, z.core.$strip>]>>;
18
+ prompt: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export type CanvasProps = z.infer<typeof CanvasPropsSchema>;
21
+ /** 清空过的一版(页面记):清空的时刻、那一版第一笔画完的时刻、几笔、清空前导出的那张图(captures/…,先 POST photos 拿到的路径) */
22
+ export declare const CanvasClearedSchema: z.ZodObject<{
23
+ at: z.ZodNumber;
24
+ from: z.ZodOptional<z.ZodNumber>;
25
+ strokes: z.ZodNumber;
26
+ image: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>;
28
+ export declare const CanvasStateSchema: z.ZodObject<{
29
+ ink: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
+ image: z.ZodOptional<z.ZodString>;
31
+ cleared: z.ZodOptional<z.ZodArray<z.ZodObject<{
32
+ at: z.ZodNumber;
33
+ from: z.ZodOptional<z.ZodNumber>;
34
+ strokes: z.ZodNumber;
35
+ image: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>>>;
37
+ }, z.core.$strip>;
38
+ export type CanvasState = z.infer<typeof CanvasStateSchema>;
39
+ /** 「画了 103 笔(黑 12、红 40、蓝 51),画了约 7 分钟,清空重画过 4 次,清掉的那几版:…(用 Read 看)」;图另写 */
40
+ export declare function canvasInkText(s: Pick<CanvasState, 'ink' | 'cleared'>): string;
41
+ export declare const canvas: CardKind<CanvasProps, CanvasState>;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * 画板卡:孩子在上面画。底图四种——课包 id(整幅终帧做底层)、行内小骨架 JSON、一张图(孩子拍的作业
3
+ * captures/… 或别的 workspace 里的图片,R5:在自己的作业照片上圈错题、写答案)、空白 + 题目;
4
+ * 舞台是舞台包里的 excalidraw 编辑器(底层锁定,孩子的笔打 customData.layer = 'ink');「给老师看」→ 导出 png 存 .cards/<n>.png,
5
+ * 状态存 ink 元素;清空前那一版存一张图(cleared);describe 给笔数、各颜色几笔、画了多久、清空过几次与图的路径,
6
+ * 老师 Read 看图(进上下文包时 runner 换成绝对路径、这轮带只读工具;看不了图就靠笔数)。
7
+ */
8
+ import { z } from 'zod';
9
+ import { BUNDLE_ID_RE, bodyLines } from "./kind.js";
10
+ import { IMAGE_EXT } from "./image.js";
11
+ import { canvasMinutesText, canvasStrokes, canvasSummary } from "../canvas-chat.js";
12
+ export const CanvasPropsSchema = z.object({
13
+ /** 底图:课包 id / 行内骨架 / 一张图(相对 workspace 根,如 captures/2026-09-14/1620-1.jpg)/ 没有(空白) */
14
+ base: z.union([z.object({ bundle: z.string().regex(BUNDLE_ID_RE) }), z.object({ skeletons: z.array(z.record(z.string(), z.unknown())).min(1).max(40) }), z.object({ image: z.string().min(1) })]).nullable(),
15
+ /** 题目(空白画板必须有;有底图时可选,画在顶栏) */
16
+ prompt: z.string().optional(),
17
+ });
18
+ /** 清空过的一版(页面记):清空的时刻、那一版第一笔画完的时刻、几笔、清空前导出的那张图(captures/…,先 POST photos 拿到的路径) */
19
+ export const CanvasClearedSchema = z.object({ at: z.number(), from: z.number().optional(), strokes: z.number().int().nonnegative(), image: z.string().optional() });
20
+ export const CanvasStateSchema = z.object({
21
+ /** 孩子画的 excalidraw 元素(customData.layer = 'ink') */
22
+ ink: z.array(z.record(z.string(), z.unknown())).max(2000),
23
+ /** 「给老师看」时导出的 png(相对 workspace 根,如 conversations/math-tutor/2026-09-10.1620-1.cards/2.png);服务端写,页面不填 */
24
+ image: z.string().optional(),
25
+ /** 清空过的几版(清空前自动存一张图,脑和家长都看得到) */
26
+ cleared: z.array(CanvasClearedSchema).max(50).optional(),
27
+ });
28
+ /** 「画了 103 笔(黑 12、红 40、蓝 51),画了约 7 分钟,清空重画过 4 次,清掉的那几版:…(用 Read 看)」;图另写 */
29
+ export function canvasInkText(s) {
30
+ const sum = canvasSummary(canvasStrokes(s.ink));
31
+ const cleared = s.cleared ?? [];
32
+ if (!sum.strokes && !cleared.length)
33
+ return '还没画';
34
+ const named = sum.colors.filter((c) => c.name !== '别的颜色');
35
+ const parts = [`画了 ${sum.strokes} 笔${named.length ? `(${named.map((c) => `${c.name} ${c.strokes}`).join('、')})` : ''}`];
36
+ const starts = [...cleared.map((c) => c.from ?? c.at), ...(sum.firstAt !== null ? [sum.firstAt] : [])].filter((x) => x > 0);
37
+ const end = sum.lastAt ?? (cleared.length ? cleared[cleared.length - 1].at : null);
38
+ if (starts.length && end !== null)
39
+ parts.push(`画了${canvasMinutesText(end - Math.min(...starts))}`);
40
+ if (cleared.length) {
41
+ const imgs = cleared.flatMap((c) => (c.image ? [c.image] : []));
42
+ parts.push(`清空重画过 ${cleared.length} 次${imgs.length ? `,清掉的那几版:${imgs.join('、')}(用 Read 看)` : ''}`);
43
+ }
44
+ return parts.join(',');
45
+ }
46
+ export const canvas = {
47
+ name: 'canvas',
48
+ props: CanvasPropsSchema,
49
+ parse(body, mods) {
50
+ const lines = bodyLines(body);
51
+ const first = lines[0] ?? '';
52
+ const rest = lines.slice(1).join(' ').trim();
53
+ const promptFromTag = mods.join(' ').trim();
54
+ if (first.startsWith('{')) {
55
+ let obj;
56
+ try {
57
+ obj = JSON.parse(lines.join('\n'));
58
+ }
59
+ catch (err) {
60
+ throw new Error(`行内骨架不是合法 JSON:${err instanceof Error ? err.message : String(err)}`);
61
+ }
62
+ const sk = obj.skeletons;
63
+ if (!Array.isArray(sk) || !sk.length)
64
+ throw new Error('行内骨架要有 skeletons 数组');
65
+ return { base: { skeletons: sk }, ...(promptFromTag ? { prompt: promptFromTag } : {}) };
66
+ }
67
+ if (first && IMAGE_EXT.test(first) && !/^https?:\/\//.test(first))
68
+ return { base: { image: first }, ...(rest || promptFromTag ? { prompt: rest || promptFromTag } : {}) };
69
+ if (first && BUNDLE_ID_RE.test(first) && !/[一-鿿]/.test(first))
70
+ return { base: { bundle: first }, ...(rest || promptFromTag ? { prompt: rest || promptFromTag } : {}) };
71
+ const prompt = [promptFromTag, ...lines].filter(Boolean).join(' ').trim();
72
+ if (!prompt)
73
+ throw new Error('空白画板要有题目(写在正文或标签后面)');
74
+ return { base: null, prompt };
75
+ },
76
+ state: CanvasStateSchema,
77
+ describe(_p, s) {
78
+ const ink = canvasInkText(s);
79
+ if (ink === '还没画')
80
+ return ink;
81
+ return `${ink}${s.image ? `,图:${s.image}(用 Read 看)` : ''}`;
82
+ },
83
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 选择题卡:问题 + 选项;答案(哪几项对)只有老师知道,不下发孩子端。
3
+ * 状态 = 孩子选了哪几项(舞台里点大按钮);「交给老师」时 describe 成「选了「B 三个」(答案:「三个」)」进上下文包——对错只在老师嘴里。
4
+ */
5
+ import { z } from 'zod';
6
+ import { type CardKind } from './kind.ts';
7
+ export declare const ChoicePropsSchema: z.ZodObject<{
8
+ question: z.ZodString;
9
+ options: z.ZodArray<z.ZodString>;
10
+ answer: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
11
+ multi: z.ZodOptional<z.ZodBoolean>;
12
+ }, z.core.$strip>;
13
+ export type ChoiceProps = z.infer<typeof ChoicePropsSchema>;
14
+ export declare const ChoiceStateSchema: z.ZodObject<{
15
+ picked: z.ZodArray<z.ZodNumber>;
16
+ }, z.core.$strip>;
17
+ export type ChoiceState = z.infer<typeof ChoiceStateSchema>;
18
+ /** 「B 三个」;下标越界只写字母 */
19
+ export declare function optionLabel(options: readonly string[], i: number): string;
20
+ export declare const choice: CardKind<ChoiceProps, ChoiceState>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 选择题卡:问题 + 选项;答案(哪几项对)只有老师知道,不下发孩子端。
3
+ * 状态 = 孩子选了哪几项(舞台里点大按钮);「交给老师」时 describe 成「选了「B 三个」(答案:「三个」)」进上下文包——对错只在老师嘴里。
4
+ */
5
+ import { z } from 'zod';
6
+ import { bodyLines } from "./kind.js";
7
+ export const ChoicePropsSchema = z.object({
8
+ question: z.string().min(1),
9
+ options: z.array(z.string().min(1)).min(1),
10
+ /** 对的选项下标(可多个);老师没标就没有 */
11
+ answer: z.array(z.number().int().nonnegative()).optional(),
12
+ /** 多选(老师标了多个 [x]);孩子端靠它决定能不能多选,答案剥掉它还在 */
13
+ multi: z.boolean().optional(),
14
+ });
15
+ export const ChoiceStateSchema = z.object({
16
+ /** 选了的下标,按点的顺序 */
17
+ picked: z.array(z.number().int().nonnegative()).max(26),
18
+ });
19
+ const OPTION = /^[-*+]\s+(?:\[([ xX])\]\s*)?(.+)$/;
20
+ const LETTER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
21
+ /** 「B 三个」;下标越界只写字母 */
22
+ export function optionLabel(options, i) {
23
+ const letter = LETTER[i] ?? String(i + 1);
24
+ return options[i] ? `${letter} ${options[i]}` : letter;
25
+ }
26
+ export const choice = {
27
+ name: 'choice',
28
+ props: ChoicePropsSchema,
29
+ parse(body) {
30
+ const question = [];
31
+ const options = [];
32
+ const answer = [];
33
+ for (const line of bodyLines(body)) {
34
+ const m = OPTION.exec(line);
35
+ if (!m) {
36
+ if (options.length)
37
+ continue; // 选项后面的散话不要
38
+ question.push(line);
39
+ continue;
40
+ }
41
+ if (m[1] && m[1] !== ' ')
42
+ answer.push(options.length);
43
+ options.push(m[2].trim());
44
+ }
45
+ if (!question.length)
46
+ throw new Error('第一行要是问题');
47
+ if (!options.length)
48
+ throw new Error('没有选项行(- [ ] 选项)');
49
+ return { question: question.join(' '), options, ...(answer.length ? { answer } : {}), ...(answer.length > 1 ? { multi: true } : {}) };
50
+ },
51
+ strip(p) {
52
+ const { answer: _drop, ...rest } = p;
53
+ return rest;
54
+ },
55
+ state: ChoiceStateSchema,
56
+ describe(p, s) {
57
+ const picked = s.picked.filter((i) => i < p.options.length);
58
+ if (!picked.length)
59
+ return '没选';
60
+ const chosen = picked.map((i) => `「${optionLabel(p.options, i)}」`).join('');
61
+ const key = p.answer?.length ? `(答案:${p.answer.map((i) => `「${optionLabel(p.options, i)}」`).join('')})` : '';
62
+ return `选了${chosen}${key}`;
63
+ },
64
+ };
@@ -0,0 +1,9 @@
1
+ /** 代码卡:原样显示。不认识的围栏标签也落到这里(老师教编程写 ```python 就正好是它)。 */
2
+ import { z } from 'zod';
3
+ import type { CardKind } from './kind.ts';
4
+ export declare const CodePropsSchema: z.ZodObject<{
5
+ lang: z.ZodNullable<z.ZodString>;
6
+ text: z.ZodString;
7
+ }, z.core.$strip>;
8
+ export type CodeProps = z.infer<typeof CodePropsSchema>;
9
+ export declare const code: CardKind<CodeProps>;
@@ -0,0 +1,10 @@
1
+ /** 代码卡:原样显示。不认识的围栏标签也落到这里(老师教编程写 ```python 就正好是它)。 */
2
+ import { z } from 'zod';
3
+ export const CodePropsSchema = z.object({ lang: z.string().nullable(), text: z.string() });
4
+ export const code = {
5
+ name: 'code',
6
+ props: CodePropsSchema,
7
+ parse(body, mods) {
8
+ return { lang: mods[0] ?? null, text: body.replace(/\s+$/, '') };
9
+ },
10
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 听写卡(kind 名 dictation,只用在首页):家长写一串词,孩子在首页点开,老师一个一个念、孩子在田字格里写,写完自己对。
3
+ * 英文单词也行:词都是英文单词时 props.lang = 'en',孩子在四线三格里写整个单词。
4
+ * 标签修饰 = 念的老师(cotutor.json 的键,用他的音色;不写用语文老师或第一位配了音色的);正文一行一个词,词后面空一格可以跟「怎么念」。
5
+ * 英文单词前面可以配一个 emoji:只在孩子写完对一对时出,写的时候看不到。
6
+ * 词就是答案:strip 只留几个词,孩子端首页 JSON 里没有字;听写页写完交了才拿到(src/app/dictation/route.ts)。
7
+ */
8
+ import { z } from 'zod';
9
+ import { type CardKind } from './kind.ts';
10
+ /** 一个词最多几个字(一个字一个田字格,同田字格卡) */
11
+ export declare const DICTATION_WORD_MAX = 4;
12
+ /** 英文单词最多几个字母(一个单词一个四线三格) */
13
+ export declare const DICTATION_EN_MAX = 20;
14
+ /** 英文单词:字母开头,可以带连字符与撇号(ice-cream、don't);不带空格,一行一个单词 */
15
+ export declare const EN_WORD_RE: RegExp;
16
+ export type DictationLang = 'zh' | 'en';
17
+ /** 能不能听写、是哪种:一到四个汉字 = zh;一个英文单词(≤ 20 个字母)= en;都不是 null */
18
+ export declare function dictationWordLang(text: string): DictationLang | null;
19
+ /** 一张卡最多几个词 */
20
+ export declare const DICTATION_WORDS_MAX = 20;
21
+ /** 念法最多几个字 */
22
+ export declare const DICTATION_SAY_MAX = 40;
23
+ /** 是一个 emoji 就回它(去掉两头空白),不是 undefined;英文单词配的图 */
24
+ export declare function dictationEmoji(v: unknown): string | undefined;
25
+ export declare const DictationWordSchema: z.ZodObject<{
26
+ chars: z.ZodString;
27
+ say: z.ZodOptional<z.ZodString>;
28
+ emoji: z.ZodOptional<z.ZodString>;
29
+ }, z.core.$strip>;
30
+ export type DictationWord = z.infer<typeof DictationWordSchema>;
31
+ export declare const DictationPropsSchema: z.ZodObject<{
32
+ tutor: z.ZodOptional<z.ZodString>;
33
+ lang: z.ZodOptional<z.ZodLiteral<"en">>;
34
+ words: z.ZodArray<z.ZodObject<{
35
+ chars: z.ZodString;
36
+ say: z.ZodOptional<z.ZodString>;
37
+ emoji: z.ZodOptional<z.ZodString>;
38
+ }, z.core.$strip>>;
39
+ count: z.ZodOptional<z.ZodNumber>;
40
+ }, z.core.$strip>;
41
+ export type DictationProps = z.infer<typeof DictationPropsSchema>;
42
+ export declare const dictation: CardKind<DictationProps>;