cotutor 0.2.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 (871) hide show
  1. package/LICENSE +247 -21
  2. package/NOTICE +42 -0
  3. package/README.md +92 -20
  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/{cli → app/cli}/cert.js +3 -3
  41. package/dist/app/cli/chalk/bake.d.ts +10 -0
  42. package/dist/app/cli/chalk/bake.js +58 -0
  43. package/dist/app/cli/chalk/browser.d.ts +16 -0
  44. package/dist/app/cli/chalk/browser.js +142 -0
  45. package/dist/app/cli/chalk/build.d.ts +14 -0
  46. package/dist/app/cli/chalk/build.js +100 -0
  47. package/dist/app/cli/chalk/dub.d.ts +51 -0
  48. package/dist/app/cli/chalk/dub.js +106 -0
  49. package/dist/app/cli/chalk/load-scene.d.ts +34 -0
  50. package/dist/app/cli/chalk/load-scene.js +117 -0
  51. package/dist/app/cli/chalk/main.d.ts +7 -0
  52. package/dist/app/cli/chalk/main.js +198 -0
  53. package/dist/app/cli/chalk/serve.d.ts +4 -0
  54. package/dist/app/cli/chalk/serve.js +28 -0
  55. package/dist/app/cli/chalk/snap.d.ts +65 -0
  56. package/dist/app/cli/chalk/snap.js +103 -0
  57. package/dist/app/cli/chalk/typecheck.d.ts +7 -0
  58. package/dist/app/cli/chalk/typecheck.js +51 -0
  59. package/dist/{cli → app/cli}/doctor.d.ts +4 -3
  60. package/dist/app/cli/doctor.js +617 -0
  61. package/dist/app/cli/grades.d.ts +14 -0
  62. package/dist/app/cli/grades.js +44 -0
  63. package/dist/{cli → app/cli}/init.d.ts +3 -1
  64. package/dist/app/cli/init.js +155 -0
  65. package/dist/app/cli/main.js +715 -0
  66. package/dist/app/cli/migrate.d.ts +58 -0
  67. package/dist/app/cli/migrate.js +253 -0
  68. package/dist/{cli → app/cli}/serve.d.ts +12 -5
  69. package/dist/app/cli/serve.js +98 -0
  70. package/dist/app/cli/shipped.d.ts +30 -0
  71. package/dist/app/cli/shipped.js +47 -0
  72. package/dist/app/cli/skeleton.d.ts +38 -0
  73. package/dist/app/cli/skeleton.js +161 -0
  74. package/dist/app/cli/skills.d.ts +55 -0
  75. package/dist/app/cli/skills.js +189 -0
  76. package/dist/app/cli/themes.d.ts +52 -0
  77. package/dist/app/cli/themes.js +148 -0
  78. package/dist/{cli → app/cli}/tutors.d.ts +15 -26
  79. package/dist/{cli → app/cli}/tutors.js +86 -110
  80. package/dist/app/cli/usage.d.ts +2 -0
  81. package/dist/app/cli/usage.js +30 -0
  82. package/dist/app/dictation/recognize.d.ts +18 -0
  83. package/dist/app/dictation/recognize.js +6 -0
  84. package/dist/app/dictation/route.d.ts +52 -0
  85. package/dist/app/dictation/route.js +510 -0
  86. package/dist/app/diff.d.ts +11 -0
  87. package/dist/app/diff.js +71 -0
  88. package/dist/app/http/access.d.ts +62 -0
  89. package/dist/app/http/access.js +180 -0
  90. package/dist/app/http/app.d.ts +246 -0
  91. package/dist/app/http/app.js +1212 -0
  92. package/dist/app/http/dev-activities.d.ts +115 -0
  93. package/dist/app/http/dev-activities.js +193 -0
  94. package/dist/app/http/dev-overview.d.ts +108 -0
  95. package/dist/app/http/dev-overview.js +209 -0
  96. package/dist/app/http/dev-tutor-files.d.ts +80 -0
  97. package/dist/app/http/dev-tutor-files.js +151 -0
  98. package/dist/app/http/parent-home.d.ts +37 -0
  99. package/dist/app/http/parent-home.js +203 -0
  100. package/dist/app/http/range.d.ts +9 -0
  101. package/dist/app/http/range.js +19 -0
  102. package/dist/app/http/raw-view.d.ts +117 -0
  103. package/dist/app/http/raw-view.js +149 -0
  104. package/dist/app/http/send-file.d.ts +7 -0
  105. package/dist/app/http/send-file.js +29 -0
  106. package/dist/{server → app/http}/stage.d.ts +9 -0
  107. package/dist/{server → app/http}/stage.js +34 -6
  108. package/dist/app/http/theme.d.ts +13 -0
  109. package/dist/app/http/theme.js +41 -0
  110. package/dist/app/machine/bailian.d.ts +28 -0
  111. package/dist/app/machine/bailian.js +88 -0
  112. package/dist/app/mock/mock-live.d.ts +16 -0
  113. package/dist/app/mock/mock-live.js +140 -0
  114. package/dist/{server → app/mock}/mock.d.ts +36 -5
  115. package/dist/app/mock/mock.js +1117 -0
  116. package/dist/app/replay.d.ts +94 -0
  117. package/dist/app/replay.js +170 -0
  118. package/dist/app/skills/analyze-doc.d.ts +3 -0
  119. package/dist/app/skills/analyze-doc.js +47 -0
  120. package/dist/app/skills/home-doc.d.ts +5 -0
  121. package/dist/app/skills/home-doc.js +112 -0
  122. package/dist/app/skills/tune-doc.d.ts +3 -0
  123. package/dist/app/skills/tune-doc.js +80 -0
  124. package/dist/app/talk/list.d.ts +11 -0
  125. package/dist/app/talk/list.js +9 -0
  126. package/dist/app/talk/route.d.ts +16 -0
  127. package/dist/app/talk/route.js +142 -0
  128. package/dist/app/workspace.d.ts +58 -0
  129. package/dist/{cli → app}/workspace.js +77 -52
  130. package/dist/app/ws/route.d.ts +25 -0
  131. package/dist/app/ws/route.js +29 -0
  132. package/dist/app/ws/ws.d.ts +31 -0
  133. package/dist/app/ws/ws.js +169 -0
  134. package/dist/board/canvas-chat.d.ts +97 -0
  135. package/dist/board/canvas-chat.js +175 -0
  136. package/dist/board/card-guards.d.ts +15 -0
  137. package/dist/board/card-guards.js +38 -0
  138. package/dist/board/cards/canvas.d.ts +41 -0
  139. package/dist/board/cards/canvas.js +83 -0
  140. package/dist/{cards → board/cards}/choice.js +0 -12
  141. package/dist/{cards → board/cards}/code.js +0 -3
  142. package/dist/board/cards/dictation.d.ts +42 -0
  143. package/dist/board/cards/dictation.js +105 -0
  144. package/dist/board/cards/docs.d.ts +47 -0
  145. package/dist/board/cards/docs.js +152 -0
  146. package/dist/{cards → board/cards}/image.js +1 -10
  147. package/dist/board/cards/index.d.ts +62 -0
  148. package/dist/board/cards/index.js +144 -0
  149. package/dist/{cards → board/cards}/kind.d.ts +10 -4
  150. package/dist/board/cards/kind.js +9 -0
  151. package/dist/board/cards/lecture.d.ts +26 -0
  152. package/dist/board/cards/lecture.js +62 -0
  153. package/dist/board/cards/paint.d.ts +38 -0
  154. package/dist/board/cards/paint.js +85 -0
  155. package/dist/board/cards/photo.d.ts +15 -0
  156. package/dist/board/cards/photo.js +29 -0
  157. package/dist/{cards → board/cards}/read.js +1 -10
  158. package/dist/board/cards/text.d.ts +20 -0
  159. package/dist/board/cards/text.js +59 -0
  160. package/dist/board/cards/tianzige.d.ts +16 -0
  161. package/dist/board/cards/tianzige.js +64 -0
  162. package/dist/board/cards/tutor.d.ts +72 -0
  163. package/dist/board/cards/tutor.js +134 -0
  164. package/dist/board/cards/word.d.ts +20 -0
  165. package/dist/board/cards/word.js +76 -0
  166. package/dist/board/lecture.d.ts +100 -0
  167. package/dist/board/lecture.js +204 -0
  168. package/dist/board/paper.d.ts +20 -0
  169. package/dist/board/paper.js +76 -0
  170. package/dist/board/parse.d.ts +120 -0
  171. package/dist/board/parse.js +330 -0
  172. package/dist/board/presentation.d.ts +295 -0
  173. package/dist/board/presentation.js +615 -0
  174. package/dist/board/sections.d.ts +16 -0
  175. package/dist/board/sections.js +130 -0
  176. package/dist/brain/api-tools.d.ts +8 -0
  177. package/dist/brain/api-tools.js +190 -0
  178. package/dist/brain/api.d.ts +62 -0
  179. package/dist/brain/api.js +411 -0
  180. package/dist/brain/cli/adapters.d.ts +60 -0
  181. package/dist/brain/cli/adapters.js +91 -0
  182. package/dist/brain/cli/qwen.d.ts +11 -0
  183. package/dist/brain/cli/qwen.js +141 -0
  184. package/dist/brain/cli/run-plan.d.ts +59 -0
  185. package/dist/brain/cli/run-plan.js +71 -0
  186. package/dist/brain/cli/run.d.ts +35 -0
  187. package/dist/brain/cli/run.js +256 -0
  188. package/dist/brain/cli/stream-json.d.ts +18 -0
  189. package/dist/brain/cli/stream-json.js +86 -0
  190. package/dist/brain/cli/types.d.ts +144 -0
  191. package/dist/brain/cli/types.js +3 -0
  192. package/dist/brain/cli/warm.d.ts +53 -0
  193. package/dist/brain/cli/warm.js +103 -0
  194. package/dist/brain/index.d.ts +145 -0
  195. package/dist/brain/index.js +74 -0
  196. package/dist/brain/stream.d.ts +20 -0
  197. package/dist/brain/stream.js +70 -0
  198. package/dist/brain/transcript.d.ts +45 -0
  199. package/dist/brain/transcript.js +132 -0
  200. package/dist/chalk/actions.d.ts +37 -0
  201. package/dist/chalk/actions.js +69 -0
  202. package/dist/chalk/bundle.d.ts +26 -0
  203. package/dist/chalk/bundle.js +69 -0
  204. package/dist/chalk/check.d.ts +28 -0
  205. package/dist/chalk/check.js +291 -0
  206. package/dist/chalk/circle.d.ts +64 -0
  207. package/dist/chalk/circle.js +193 -0
  208. package/dist/chalk/clock.d.ts +84 -0
  209. package/dist/chalk/clock.js +84 -0
  210. package/dist/chalk/geometry.d.ts +44 -0
  211. package/dist/chalk/geometry.js +139 -0
  212. package/dist/chalk/glyphs/capitals.d.ts +12 -0
  213. package/dist/chalk/glyphs/capitals.js +264 -0
  214. package/dist/chalk/glyphs/index.d.ts +21 -0
  215. package/dist/chalk/glyphs/index.js +18 -0
  216. package/dist/chalk/glyphs/letters.d.ts +13 -0
  217. package/dist/chalk/glyphs/letters.js +280 -0
  218. package/dist/chalk/glyphs/metrics.d.ts +33 -0
  219. package/dist/chalk/glyphs/metrics.js +28 -0
  220. package/dist/chalk/glyphs/registry.d.ts +7 -0
  221. package/dist/chalk/glyphs/registry.js +8 -0
  222. package/dist/chalk/glyphs/sample.d.ts +32 -0
  223. package/dist/chalk/glyphs/sample.js +102 -0
  224. package/dist/chalk/glyphs/skeleton.d.ts +64 -0
  225. package/dist/chalk/glyphs/skeleton.js +126 -0
  226. package/dist/chalk/glyphs/types.d.ts +58 -0
  227. package/dist/chalk/glyphs/types.js +17 -0
  228. package/dist/chalk/index.d.ts +23 -0
  229. package/dist/chalk/index.js +15 -0
  230. package/dist/chalk/manifest.d.ts +41 -0
  231. package/dist/chalk/manifest.js +6 -0
  232. package/dist/chalk/paint.d.ts +180 -0
  233. package/dist/chalk/paint.js +210 -0
  234. package/dist/chalk/pointer.d.ts +8 -0
  235. package/dist/chalk/pointer.js +21 -0
  236. package/dist/chalk/prepare.d.ts +11 -0
  237. package/dist/chalk/prepare.js +15 -0
  238. package/dist/chalk/scene-schema.d.ts +199 -0
  239. package/dist/chalk/scene-schema.js +91 -0
  240. package/dist/chalk/seed.d.ts +3 -0
  241. package/dist/chalk/seed.js +10 -0
  242. package/dist/chalk/text-metrics.d.ts +8 -0
  243. package/dist/chalk/text-metrics.js +156 -0
  244. package/dist/chalk/timeline.d.ts +47 -0
  245. package/dist/chalk/timeline.js +84 -0
  246. package/dist/chalk/types.d.ts +150 -0
  247. package/dist/chalk/types.js +8 -0
  248. package/dist/lib/index.d.ts +14 -12
  249. package/dist/lib/index.js +14 -12
  250. package/dist/media/draw.d.ts +23 -0
  251. package/dist/media/draw.js +44 -0
  252. package/dist/media/mp3.d.ts +6 -0
  253. package/dist/media/mp3.js +58 -0
  254. package/dist/media/mp4.d.ts +1 -0
  255. package/dist/media/mp4.js +58 -0
  256. package/dist/media/tts-voices.d.ts +18 -0
  257. package/dist/media/tts-voices.js +606 -0
  258. package/dist/media/tts.d.ts +56 -0
  259. package/dist/media/tts.js +174 -0
  260. package/dist/media/vision.d.ts +25 -0
  261. package/dist/media/vision.js +71 -0
  262. package/dist/memory/commit.d.ts +67 -0
  263. package/dist/memory/commit.js +130 -0
  264. package/dist/memory/context.d.ts +86 -0
  265. package/dist/memory/context.js +97 -0
  266. package/dist/memory/diary.d.ts +84 -0
  267. package/dist/memory/diary.js +183 -0
  268. package/dist/memory/grade.d.ts +2 -0
  269. package/dist/memory/grade.js +7 -0
  270. package/dist/{lib → memory}/plan.d.ts +1 -1
  271. package/dist/{lib → memory}/plan.js +1 -1
  272. package/dist/memory/proposals.d.ts +11 -0
  273. package/dist/memory/proposals.js +43 -0
  274. package/dist/memory/retrieval.d.ts +44 -0
  275. package/dist/memory/retrieval.js +157 -0
  276. package/dist/{lib → memory}/timetable.d.ts +0 -3
  277. package/dist/{lib → memory}/timetable.js +0 -11
  278. package/dist/memory/vault-notes.d.ts +165 -0
  279. package/dist/memory/vault-notes.js +359 -0
  280. package/dist/memory/vault.d.ts +70 -0
  281. package/dist/memory/vault.js +169 -0
  282. package/dist/realtime/bailian.d.ts +120 -0
  283. package/dist/realtime/bailian.js +288 -0
  284. package/dist/realtime/cues.d.ts +51 -0
  285. package/dist/realtime/cues.js +94 -0
  286. package/dist/realtime/listen.d.ts +32 -0
  287. package/dist/realtime/listen.js +53 -0
  288. package/dist/realtime/preview.d.ts +23 -0
  289. package/dist/realtime/preview.js +38 -0
  290. package/dist/realtime/prompt.d.ts +8 -0
  291. package/dist/realtime/prompt.js +13 -0
  292. package/dist/realtime/voices.d.ts +19 -0
  293. package/dist/realtime/voices.js +71 -0
  294. package/dist/runtime/activities.d.ts +17 -0
  295. package/dist/runtime/activities.js +46 -0
  296. package/dist/runtime/activity-state.d.ts +22 -0
  297. package/dist/runtime/activity-state.js +83 -0
  298. package/dist/runtime/activity.d.ts +63 -0
  299. package/dist/runtime/activity.js +428 -0
  300. package/dist/runtime/agent-file.d.ts +24 -0
  301. package/dist/runtime/agent-file.js +59 -0
  302. package/dist/runtime/auto-bookkeep.d.ts +30 -0
  303. package/dist/runtime/auto-bookkeep.js +84 -0
  304. package/dist/{lib → runtime/context}/context-pack.d.ts +3 -3
  305. package/dist/runtime/context/context-pack.js +182 -0
  306. package/dist/runtime/context/thread-digest.d.ts +4 -0
  307. package/dist/runtime/context/thread-digest.js +35 -0
  308. package/dist/runtime/context/tutor-rules.d.ts +25 -0
  309. package/dist/runtime/context/tutor-rules.js +47 -0
  310. package/dist/runtime/delivery/delivery.d.ts +94 -0
  311. package/dist/runtime/delivery/delivery.js +145 -0
  312. package/dist/runtime/delivery/playback.d.ts +25 -0
  313. package/dist/runtime/delivery/playback.js +29 -0
  314. package/dist/runtime/delivery/player.d.ts +145 -0
  315. package/dist/runtime/delivery/player.js +221 -0
  316. package/dist/runtime/delivery/queue.d.ts +89 -0
  317. package/dist/runtime/delivery/queue.js +59 -0
  318. package/dist/runtime/home/edit.d.ts +39 -0
  319. package/dist/runtime/home/edit.js +132 -0
  320. package/dist/runtime/home/home.d.ts +180 -0
  321. package/dist/runtime/home/home.js +311 -0
  322. package/dist/runtime/home/store.d.ts +142 -0
  323. package/dist/runtime/home/store.js +440 -0
  324. package/dist/runtime/journal/conversation.d.ts +46 -0
  325. package/dist/runtime/journal/conversation.js +89 -0
  326. package/dist/runtime/journal/events.d.ts +27 -0
  327. package/dist/runtime/journal/events.js +136 -0
  328. package/dist/runtime/journal/kid-log.d.ts +105 -0
  329. package/dist/runtime/journal/kid-log.js +133 -0
  330. package/dist/runtime/journal/ledger.d.ts +17 -0
  331. package/dist/{lib → runtime/journal}/ledger.js +7 -40
  332. package/dist/runtime/journal/mix.d.ts +33 -0
  333. package/dist/runtime/journal/mix.js +88 -0
  334. package/dist/runtime/journal/mouth-index.d.ts +26 -0
  335. package/dist/runtime/journal/mouth-index.js +34 -0
  336. package/dist/runtime/journal/mouth.d.ts +54 -0
  337. package/dist/runtime/journal/mouth.js +102 -0
  338. package/dist/runtime/journal/recorder.d.ts +46 -0
  339. package/dist/runtime/journal/recorder.js +58 -0
  340. package/dist/runtime/journal/store.d.ts +123 -0
  341. package/dist/runtime/journal/store.js +316 -0
  342. package/dist/runtime/kid-input.d.ts +16 -0
  343. package/dist/runtime/kid-input.js +195 -0
  344. package/dist/runtime/kid-view.d.ts +124 -0
  345. package/dist/runtime/kid-view.js +157 -0
  346. package/dist/runtime/lecture.d.ts +86 -0
  347. package/dist/runtime/lecture.js +237 -0
  348. package/dist/runtime/live/call.d.ts +219 -0
  349. package/dist/runtime/live/call.js +1211 -0
  350. package/dist/runtime/live/turns.d.ts +48 -0
  351. package/dist/runtime/live/turns.js +102 -0
  352. package/dist/runtime/runner.d.ts +289 -0
  353. package/dist/runtime/runner.js +898 -0
  354. package/dist/runtime/talk-run.d.ts +21 -0
  355. package/dist/runtime/talk-run.js +34 -0
  356. package/dist/scenes/dictation/match.d.ts +57 -0
  357. package/dist/scenes/dictation/match.js +255 -0
  358. package/dist/scenes/dictation/recognize.d.ts +86 -0
  359. package/dist/scenes/dictation/recognize.js +163 -0
  360. package/dist/scenes/dictation/store.d.ts +112 -0
  361. package/dist/scenes/dictation/store.js +99 -0
  362. package/dist/scenes/look.d.ts +26 -0
  363. package/dist/scenes/look.js +1 -0
  364. package/dist/scenes/paint/painter.d.ts +84 -0
  365. package/dist/scenes/paint/painter.js +170 -0
  366. package/dist/scenes/paint/prompt.d.ts +23 -0
  367. package/dist/scenes/paint/prompt.js +36 -0
  368. package/dist/scenes/talk/en-words.d.ts +8 -0
  369. package/dist/scenes/talk/en-words.js +44 -0
  370. package/dist/scenes/talk/list.d.ts +44 -0
  371. package/dist/scenes/talk/list.js +88 -0
  372. package/dist/scenes/talk/store.d.ts +27 -0
  373. package/dist/scenes/talk/store.js +61 -0
  374. package/dist/scenes/talk/warmup.d.ts +16 -0
  375. package/dist/scenes/talk/warmup.js +39 -0
  376. package/dist/schema/activity.d.ts +149 -0
  377. package/dist/schema/activity.js +113 -0
  378. package/dist/schema/board.d.ts +143 -2
  379. package/dist/schema/board.js +15 -3
  380. package/dist/schema/config.d.ts +309 -94
  381. package/dist/schema/config.js +259 -72
  382. package/dist/schema/context-pack.d.ts +76 -14
  383. package/dist/schema/context-pack.js +91 -10
  384. package/dist/{lib/conversation.d.ts → schema/conversation-files.d.ts} +11 -33
  385. package/dist/schema/conversation-files.js +26 -0
  386. package/dist/schema/conversation.d.ts +385 -49
  387. package/dist/schema/conversation.js +135 -19
  388. package/dist/schema/events.d.ts +138 -0
  389. package/dist/schema/events.js +1 -0
  390. package/dist/schema/home.d.ts +46 -0
  391. package/dist/schema/home.js +30 -0
  392. package/dist/schema/index.d.ts +14 -3
  393. package/dist/schema/index.js +14 -3
  394. package/dist/schema/kid-device.d.ts +20 -0
  395. package/dist/schema/kid-device.js +32 -0
  396. package/dist/schema/ledger.d.ts +8 -63
  397. package/dist/schema/ledger.js +7 -31
  398. package/dist/schema/memory.d.ts +73 -0
  399. package/dist/schema/memory.js +47 -0
  400. package/dist/schema/plan.d.ts +2 -2
  401. package/dist/schema/plan.js +2 -2
  402. package/dist/schema/sections.d.ts +32 -25
  403. package/dist/schema/sections.js +21 -22
  404. package/dist/schema/theme.d.ts +25 -0
  405. package/dist/schema/theme.js +26 -0
  406. package/dist/schema/timetable.d.ts +2 -2
  407. package/dist/schema/timetable.js +2 -2
  408. package/dist/schema/workspace.d.ts +41 -0
  409. package/dist/schema/workspace.js +9 -0
  410. package/dist/shared/errors.d.ts +8 -0
  411. package/dist/shared/errors.js +13 -0
  412. package/dist/shared/home.d.ts +2 -0
  413. package/dist/shared/home.js +16 -0
  414. package/dist/shared/human-notes.d.ts +5 -0
  415. package/dist/shared/human-notes.js +7 -0
  416. package/dist/shared/qianwen.d.ts +50 -0
  417. package/dist/shared/qianwen.js +109 -0
  418. package/dist/shared/time.d.ts +9 -0
  419. package/dist/shared/time.js +22 -0
  420. package/dist/shared/tokens.d.ts +18 -0
  421. package/dist/shared/tokens.js +11 -0
  422. package/dist/shared/wav.d.ts +10 -0
  423. package/dist/shared/wav.js +50 -0
  424. package/dist/stage/chunk-226TNLQA.js +129 -0
  425. package/dist/stage/chunk-24LGQEKE.js +1 -0
  426. package/dist/stage/chunk-25XV6UY3.js +10 -0
  427. package/dist/stage/chunk-2AZI3NHJ.js +1 -0
  428. package/dist/stage/chunk-2BQZTTBE.js +1 -0
  429. package/dist/stage/chunk-2M7CGY3Y.js +11 -0
  430. package/dist/stage/chunk-2VR4WFQ7.js +10 -0
  431. package/dist/stage/chunk-2ZYXBUWG.js +9 -0
  432. package/dist/stage/chunk-32LAWMGY.js +1 -0
  433. package/dist/stage/chunk-3LEMTSOO.js +11 -0
  434. package/dist/stage/chunk-3QCKGZYE.js +32 -0
  435. package/dist/stage/chunk-44P66WFA.js +1 -0
  436. package/dist/stage/chunk-4AM6FRR6.js +7 -0
  437. package/dist/stage/chunk-4QDE4SUK.js +1 -0
  438. package/dist/stage/chunk-4QESHV3U.js +1 -0
  439. package/dist/stage/chunk-4SG5QPHB.js +2 -0
  440. package/dist/stage/chunk-4T4UVCOC.js +1 -0
  441. package/dist/stage/chunk-4WUEPPG3.js +34 -0
  442. package/dist/stage/chunk-4YCN6UZ5.js +99 -0
  443. package/dist/stage/chunk-5V7ZY2AP.js +1 -0
  444. package/dist/stage/chunk-5VS5Y2VJ.js +6 -0
  445. package/dist/stage/chunk-5W4NO2ZD.js +62 -0
  446. package/dist/stage/chunk-65CRNICM.js +1 -0
  447. package/dist/stage/chunk-66MULO7F.js +5 -0
  448. package/dist/stage/chunk-6COFQTBS.js +162 -0
  449. package/dist/stage/chunk-6VZG3M3I.js +8 -0
  450. package/dist/stage/chunk-7HVDH43T.js +1 -0
  451. package/dist/stage/chunk-7JLJN4EZ.js +8 -0
  452. package/dist/stage/chunk-7QDSP4LN.js +1 -0
  453. package/dist/stage/chunk-7R6OQAO3.js +1 -0
  454. package/dist/stage/chunk-7VTTHZKW.js +7 -0
  455. package/dist/stage/chunk-ATHR5KEN.js +10 -0
  456. package/dist/stage/chunk-B6R5LTP2.js +36 -0
  457. package/dist/stage/chunk-BD4WE264.js +1 -0
  458. package/dist/stage/chunk-BONANU47.js +206 -0
  459. package/dist/stage/chunk-BTVW7OFK.js +89 -0
  460. package/dist/stage/chunk-BUTJIDHG.js +8 -0
  461. package/dist/stage/chunk-C2IPYMML.js +84 -0
  462. package/dist/stage/chunk-C54FTPPV.js +9 -0
  463. package/dist/stage/chunk-C6LOUF2Z.js +90 -0
  464. package/dist/stage/chunk-CFF3PILO.js +339 -0
  465. package/dist/stage/chunk-CI2FQ2JY.js +9 -0
  466. package/dist/stage/chunk-CW5O4RV7.js +12 -0
  467. package/dist/stage/chunk-CYABNQYD.js +1 -0
  468. package/dist/stage/chunk-D7FFA4NS.js +15 -0
  469. package/dist/stage/chunk-DUNNXU6Z.js +8 -0
  470. package/dist/stage/chunk-E3E4Q6JF.js +6 -0
  471. package/dist/stage/chunk-EB3U3LH7.js +9 -0
  472. package/dist/stage/chunk-EGSZ736B.js +8 -0
  473. package/dist/stage/chunk-EOBXW5VQ.js +2 -0
  474. package/dist/stage/chunk-ERZC3B7Y.js +11 -0
  475. package/dist/stage/chunk-ESDOOBIH.js +11 -0
  476. package/dist/stage/chunk-EVU4QAL4.js +178 -0
  477. package/dist/stage/chunk-EVVZI2NY.js +39 -0
  478. package/dist/stage/chunk-FBKAZUKD.js +39 -0
  479. package/dist/stage/chunk-FDVKYQJN.js +1 -0
  480. package/dist/stage/chunk-FGPVYHVR.js +5 -0
  481. package/dist/stage/chunk-FHUD4AZC.js +1 -0
  482. package/dist/stage/chunk-FKUJ2DMY.js +96 -0
  483. package/dist/stage/chunk-FNZGVIJV.js +1 -0
  484. package/dist/stage/chunk-GBYSEGYM.js +78 -0
  485. package/dist/stage/chunk-GCO4TDHX.js +1 -0
  486. package/dist/stage/chunk-GKTML2LG.js +10 -0
  487. package/dist/stage/chunk-GMDIHHXQ.js +11 -0
  488. package/dist/stage/chunk-GOUNACI3.js +10 -0
  489. package/dist/stage/chunk-GXAYATPF.js +3 -0
  490. package/dist/stage/chunk-H2K2DDXV.js +8 -0
  491. package/dist/stage/chunk-H3UJI6ZY.js +13 -0
  492. package/dist/stage/chunk-H6PUGCME.js +7 -0
  493. package/dist/stage/chunk-HNBUIMIG.js +1 -0
  494. package/dist/stage/chunk-HRZY2BJQ.js +10 -0
  495. package/dist/stage/chunk-HSPJGALW.js +30 -0
  496. package/dist/stage/chunk-IBYORHIP.js +25 -0
  497. package/dist/stage/chunk-IHF4EWTY.js +1 -0
  498. package/dist/stage/chunk-ISBRPNKI.js +1 -0
  499. package/dist/stage/chunk-IZ3OI3C2.js +2 -0
  500. package/dist/stage/chunk-JEFZAC2R.js +1 -0
  501. package/dist/stage/chunk-JFIGRDPO.js +1 -0
  502. package/dist/stage/chunk-JFVYBOOC.js +9 -0
  503. package/dist/stage/chunk-JGD4TUTQ.js +1 -0
  504. package/dist/stage/chunk-JO4BEHDH.js +4 -0
  505. package/dist/stage/chunk-JOWBS42C.js +1 -0
  506. package/dist/stage/chunk-JP3TM2TG.js +1 -0
  507. package/dist/stage/chunk-JVK2C52O.js +1 -0
  508. package/dist/stage/chunk-K4I76XBX.js +14 -0
  509. package/dist/stage/chunk-KA6CZZ4M.js +1 -0
  510. package/dist/stage/chunk-KESSJ36M.js +1 -0
  511. package/dist/stage/chunk-LKATEVRU.js +1 -0
  512. package/dist/stage/chunk-LS4EJ2EI.js +1 -0
  513. package/dist/stage/chunk-LUKJQC2X.js +70 -0
  514. package/dist/stage/chunk-LWULR3SM.js +1 -0
  515. package/dist/stage/chunk-LWVRFMKX.js +2 -0
  516. package/dist/stage/chunk-LXC4ZBPZ.js +1 -0
  517. package/dist/stage/chunk-M2UP255H.js +1 -0
  518. package/dist/stage/chunk-MAPPXUZQ.js +231 -0
  519. package/dist/stage/chunk-MBMPW7Z5.js +1 -0
  520. package/dist/stage/chunk-MD3HMMTK.js +1 -0
  521. package/dist/stage/chunk-MLPCUIKR.js +17 -0
  522. package/dist/stage/chunk-MNQIRPDQ.js +8 -0
  523. package/dist/stage/chunk-MRG7MJVS.js +1 -0
  524. package/dist/stage/chunk-MU6EXW72.js +10 -0
  525. package/dist/stage/chunk-MVU2X6LU.js +4 -0
  526. package/dist/stage/chunk-N6UA5CZV.js +36 -0
  527. package/dist/stage/chunk-NLZIT2TJ.js +7 -0
  528. package/dist/stage/chunk-NOJR3J7M.js +1 -0
  529. package/dist/stage/chunk-NT7ARDOL.js +1 -0
  530. package/dist/stage/chunk-NWOGMPZH.js +1 -0
  531. package/dist/stage/chunk-NXE4KMG3.js +40 -0
  532. package/dist/stage/chunk-O4YCZXD2.js +257 -0
  533. package/dist/stage/chunk-OAJZ7HLK.js +1 -0
  534. package/dist/stage/chunk-OCFCFASO.js +1 -0
  535. package/dist/stage/chunk-ODGPG5RY.js +7 -0
  536. package/dist/stage/chunk-ODUEA52Q.js +3 -0
  537. package/dist/stage/chunk-OGDJ3FCI.js +1 -0
  538. package/dist/stage/chunk-OLDJ55TT.js +1 -0
  539. package/dist/stage/chunk-OOCL4ATI.js +2 -0
  540. package/dist/stage/chunk-OQEFDUDV.js +1 -0
  541. package/dist/stage/chunk-OQWVEWG7.js +4 -0
  542. package/dist/stage/chunk-OUIX6BGK.js +1 -0
  543. package/dist/stage/chunk-OV7OZYUO.js +7 -0
  544. package/dist/stage/chunk-PFGDY33O.js +1 -0
  545. package/dist/stage/chunk-PFJDUJB3.js +139 -0
  546. package/dist/stage/chunk-PGEW76ER.js +1 -0
  547. package/dist/stage/chunk-PP76TAQX.js +32 -0
  548. package/dist/stage/chunk-PTBOP4OT.js +2 -0
  549. package/dist/stage/chunk-PX2RVHCK.js +1 -0
  550. package/dist/stage/chunk-Q7K3PNAD.js +1 -0
  551. package/dist/stage/chunk-QDDPLZDB.js +1 -0
  552. package/dist/stage/chunk-QLGLZ77F.js +1 -0
  553. package/dist/stage/chunk-QOPFDFHI.js +1 -0
  554. package/dist/stage/chunk-QXT4KAEJ.js +1 -0
  555. package/dist/stage/chunk-R4YVZCIT.js +1 -0
  556. package/dist/stage/chunk-R6P6EHWA.js +62 -0
  557. package/dist/stage/chunk-RCH3OXBI.js +9 -0
  558. package/dist/stage/chunk-RHPE44I2.js +1 -0
  559. package/dist/stage/chunk-RJ2R4FVC.js +1 -0
  560. package/dist/stage/chunk-RJH2YVTD.js +1 -0
  561. package/dist/stage/chunk-RLWWW5OB.js +6 -0
  562. package/dist/stage/chunk-S3WO35Z7.js +120 -0
  563. package/dist/stage/chunk-S7ZGX6MW.js +1 -0
  564. package/dist/stage/chunk-SIAWX27B.js +1 -0
  565. package/dist/stage/chunk-SLG4X622.js +1 -0
  566. package/dist/stage/chunk-SLJRBC77.js +168 -0
  567. package/dist/stage/chunk-SRORWQJZ.js +1 -0
  568. package/dist/stage/chunk-STZTUIIF.js +2 -0
  569. package/dist/stage/chunk-SVQ6MWNV.js +9 -0
  570. package/dist/stage/chunk-TL3HLL2S.js +132 -0
  571. package/dist/stage/chunk-U3DOE6SF.js +24 -0
  572. package/dist/stage/chunk-UABQIZKW.js +6 -0
  573. package/dist/stage/chunk-UDK3R764.js +1 -0
  574. package/dist/stage/chunk-UFF4E54B.js +41 -0
  575. package/dist/stage/chunk-UFP5Q4AY.js +1 -0
  576. package/dist/stage/chunk-UMH2TSW2.js +72 -0
  577. package/dist/stage/chunk-UTASVNF5.js +10 -0
  578. package/dist/stage/chunk-UW7ML5ML.js +88 -0
  579. package/dist/stage/chunk-V3J7F6OP.js +1 -0
  580. package/dist/stage/chunk-VEHP5B5Q.js +5 -0
  581. package/dist/stage/chunk-VRXWB733.js +9 -0
  582. package/dist/stage/chunk-VVDHBBS5.js +5 -0
  583. package/dist/stage/chunk-VYFOH6FU.js +106 -0
  584. package/dist/stage/chunk-W3VZTLQS.js +3 -0
  585. package/dist/stage/chunk-W7WNRWTZ.js +8 -0
  586. package/dist/stage/chunk-WHUCV53C.js +1 -0
  587. package/dist/stage/chunk-WULMYHIF.js +1 -0
  588. package/dist/stage/chunk-X54EX7AW.js +9 -0
  589. package/dist/stage/chunk-X565ISZM.js +1 -0
  590. package/dist/stage/chunk-XGZMDECB.js +1 -0
  591. package/dist/stage/chunk-XHONC4RF.js +172 -0
  592. package/dist/stage/chunk-XIK4XQ6E.js +24 -0
  593. package/dist/stage/chunk-XJQQWFTE.js +1 -0
  594. package/dist/stage/chunk-XM4WOU3I.js +13 -0
  595. package/dist/stage/chunk-XM7Y5HP5.js +38 -0
  596. package/dist/stage/chunk-XNYYRGD5.js +292 -0
  597. package/dist/stage/chunk-XOYVR3SV.js +1 -0
  598. package/dist/stage/chunk-XQIW5HCE.js +1 -0
  599. package/dist/stage/chunk-YEWL7FUW.js +8 -0
  600. package/dist/stage/chunk-YI55PY3V.js +1 -0
  601. package/dist/stage/chunk-YM63HI6W.js +1 -0
  602. package/dist/stage/chunk-YNLGLU4P.js +9 -0
  603. package/dist/stage/chunk-YTNMNOWP.js +1 -0
  604. package/dist/stage/chunk-YV62XKTC.js +1 -0
  605. package/dist/stage/chunk-YVBA3QW6.js +1 -0
  606. package/dist/stage/chunk-Z2SY2HOC.js +1 -0
  607. package/dist/stage/chunk-ZBTCQEBK.js +10 -0
  608. package/dist/stage/chunk-ZCUFN74D.js +1 -0
  609. package/dist/stage/chunk-ZHOULXEJ.js +11 -0
  610. package/dist/stage/chunk-ZTRZIET2.js +1 -0
  611. package/dist/stage/index.html +1 -0
  612. package/dist/stage/stage.css +1 -1
  613. package/dist/stage/stage.js +1 -4383
  614. package/dist/ui/dev/dev-page.d.ts +1 -0
  615. package/dist/ui/dev/dev-page.js +2248 -0
  616. package/dist/ui/dev/dev-theme.d.ts +6 -0
  617. package/dist/ui/dev/dev-theme.js +67 -0
  618. package/dist/ui/dev/qr-page.d.ts +8 -0
  619. package/dist/ui/dev/qr-page.js +61 -0
  620. package/dist/ui/dev/voice-gallery-page.d.ts +1 -0
  621. package/dist/ui/dev/voice-gallery-page.js +121 -0
  622. package/dist/ui/dev/voice-scenes.d.ts +21 -0
  623. package/dist/ui/dev/voice-scenes.js +30 -0
  624. package/dist/ui/dictation/en-box.d.ts +2 -0
  625. package/dist/ui/dictation/en-box.js +86 -0
  626. package/dist/ui/dictation/en-page.d.ts +1 -0
  627. package/dist/ui/dictation/en-page.js +484 -0
  628. package/dist/ui/dictation/page.d.ts +1 -0
  629. package/dist/ui/dictation/page.js +1084 -0
  630. package/dist/ui/dictation/parent-page.d.ts +1 -0
  631. package/dist/ui/dictation/parent-page.js +234 -0
  632. package/dist/ui/dictation/reel-mode.d.ts +1 -0
  633. package/dist/ui/dictation/reel-mode.js +87 -0
  634. package/dist/ui/dictation/reel-page.d.ts +1 -0
  635. package/dist/ui/dictation/reel-page.js +62 -0
  636. package/dist/ui/dictation/reel.d.ts +163 -0
  637. package/dist/ui/dictation/reel.js +436 -0
  638. package/dist/ui/dictation/ui.d.ts +44 -0
  639. package/dist/ui/dictation/ui.js +80 -0
  640. package/dist/ui/dictation/unlock.d.ts +7 -0
  641. package/dist/ui/dictation/unlock.js +16 -0
  642. package/dist/ui/kid/audio-client.d.ts +11 -0
  643. package/dist/ui/kid/audio-client.js +74 -0
  644. package/dist/ui/kid/board-mark-art.d.ts +37 -0
  645. package/dist/ui/kid/board-mark-art.js +5 -0
  646. package/dist/ui/kid/board-mark.d.ts +24 -0
  647. package/dist/ui/kid/board-mark.js +58 -0
  648. package/dist/ui/kid/kid-log.d.ts +15 -0
  649. package/dist/ui/kid/kid-log.js +87 -0
  650. package/dist/ui/kid/kid-nav.d.ts +11 -0
  651. package/dist/ui/kid/kid-nav.js +22 -0
  652. package/dist/ui/kid/kid-page.d.ts +9 -0
  653. package/dist/ui/kid/kid-page.js +3719 -0
  654. package/dist/ui/kid/letters.d.ts +26 -0
  655. package/dist/ui/kid/letters.js +51 -0
  656. package/dist/ui/kid/photo-edit.d.ts +83 -0
  657. package/dist/ui/kid/photo-edit.js +106 -0
  658. package/dist/ui/kid/photo-ui.d.ts +23 -0
  659. package/dist/ui/kid/photo-ui.js +60 -0
  660. package/dist/ui/kid/reel.d.ts +419 -0
  661. package/dist/ui/kid/reel.js +648 -0
  662. package/dist/ui/kid/tianzige.d.ts +8 -0
  663. package/dist/ui/kid/tianzige.js +45 -0
  664. package/dist/ui/kid/tutor-face.d.ts +35 -0
  665. package/dist/ui/kid/tutor-face.js +84 -0
  666. package/dist/ui/kid/voice-ui.d.ts +70 -0
  667. package/dist/ui/kid/voice-ui.js +316 -0
  668. package/dist/ui/kid/voice-view.d.ts +71 -0
  669. package/dist/ui/kid/voice-view.js +75 -0
  670. package/dist/ui/kid/word-draw.d.ts +2 -0
  671. package/dist/ui/kid/word-draw.js +107 -0
  672. package/dist/ui/kid/word-emoji.d.ts +10 -0
  673. package/dist/ui/kid/word-emoji.js +66 -0
  674. package/dist/ui/kid/word-layout.d.ts +25 -0
  675. package/dist/ui/kid/word-layout.js +29 -0
  676. package/dist/ui/parent/parent-home-page.d.ts +1 -0
  677. package/dist/ui/parent/parent-home-page.js +414 -0
  678. package/dist/ui/parent/parent-page.d.ts +2 -0
  679. package/dist/ui/parent/parent-page.js +507 -0
  680. package/dist/ui/shared/brand.d.ts +36 -0
  681. package/dist/ui/shared/brand.js +51 -0
  682. package/dist/ui/shared/favicon.d.ts +12 -0
  683. package/dist/ui/shared/favicon.js +96 -0
  684. package/dist/ui/shared/icon.d.ts +9 -0
  685. package/dist/ui/shared/icon.js +35 -0
  686. package/dist/ui/shared/inline-lib.d.ts +1 -0
  687. package/dist/ui/shared/inline-lib.js +28 -0
  688. package/dist/ui/shared/logo.d.ts +31 -0
  689. package/dist/ui/shared/logo.js +43 -0
  690. package/dist/ui/shared/page-dom.d.ts +12 -0
  691. package/dist/ui/shared/page-dom.js +36 -0
  692. package/dist/ui/shared/png.d.ts +1 -0
  693. package/dist/ui/shared/png.js +45 -0
  694. package/dist/ui/shared/qr-svg.d.ts +3 -0
  695. package/dist/ui/shared/qr-svg.js +32 -0
  696. package/dist/ui/shared/qr.d.ts +14 -0
  697. package/dist/ui/shared/qr.js +281 -0
  698. package/dist/ui/shared/reel-dock.d.ts +22 -0
  699. package/dist/ui/shared/reel-dock.js +365 -0
  700. package/dist/ui/shared/tutor-color.d.ts +15 -0
  701. package/dist/ui/shared/tutor-color.js +47 -0
  702. package/dist/ui/talk/page.d.ts +6 -0
  703. package/dist/ui/talk/page.js +294 -0
  704. package/grades/grade-2/README.md +11 -0
  705. package/grades/grade-2/VALIDATION.md +41 -0
  706. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273.md +157 -0
  707. 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
  708. 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
  709. 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
  710. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235.md +64 -0
  711. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235./344/276/213/345/255/220.md +31 -0
  712. package/grades/grade-2/agents/chinese-tutor/activities//345/220/254/345/206/231.md +48 -0
  713. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240.md +79 -0
  714. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  715. package/grades/grade-2/agents/chinese-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  716. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271.md +81 -0
  717. package/grades/grade-2/agents/chinese-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  718. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235.md +94 -0
  719. 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
  720. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240.md +82 -0
  721. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  722. package/grades/grade-2/agents/chinese-tutor.md +59 -0
  723. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276.md +149 -0
  724. 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
  725. package/grades/grade-2/agents/english-tutor/activities//345/220/254/345/206/231.md +47 -0
  726. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240.md +78 -0
  727. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  728. package/grades/grade-2/agents/english-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  729. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271.md +80 -0
  730. package/grades/grade-2/agents/english-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  731. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240.md +86 -0
  732. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  733. package/grades/grade-2/agents/english-tutor.md +57 -0
  734. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240.md +78 -0
  735. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  736. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202.md +56 -0
  737. 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
  738. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271.md +80 -0
  739. package/grades/grade-2/agents/math-tutor/activities//346/211/271/346/224/271./344/276/213/345/255/220.md +35 -0
  740. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240.md +81 -0
  741. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  742. package/grades/grade-2/agents/math-tutor.md +51 -0
  743. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/index.json +44 -0
  744. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-1.mp3 +0 -0
  745. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-2.mp3 +0 -0
  746. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-3.mp3 +0 -0
  747. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-4.mp3 +0 -0
  748. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-5.mp3 +0 -0
  749. package/grades/grade-2/examples/2026-10-27-pingjunfen/bake.json +1 -0
  750. package/grades/grade-2/examples/2026-10-27-pingjunfen/manifest.json +63 -0
  751. package/grades/grade-2/examples/2026-10-27-pingjunfen/scene.json +247 -0
  752. package/grades/grade-2/examples/2026-10-27-pingjunfen.md +40 -0
  753. package/grades/grade-2/examples/2026-10-27-pingjunfen.ts +26 -0
  754. package/grades/grade-2/examples//345/271/263/345/235/207/345/210/206./344/276/213/345/255/220.md +24 -0
  755. package/grades/grade-2/examples//346/225/260/345/255/246/345/271/263/345/235/207/345/210/206.md +42 -0
  756. package/grades/grade-2/validation/2026-10-27.json +4410 -0
  757. package/package.json +26 -15
  758. package/skills/chalk-cli/SKILL.md +62 -0
  759. package/skills/chalk-scene/SKILL.md +91 -0
  760. package/skills/chalk-teaching/SKILL.md +82 -0
  761. 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
  762. package/skills/chalk-teaching/models//345/207/221/345/215/201.md +7 -0
  763. package/skills/chalk-teaching/models//345/221/250/346/234/237/350/247/204/345/276/213.md +6 -0
  764. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/345/242/236/345/207/217.md +6 -0
  765. 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
  766. 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
  767. package/skills/chalk-teaching/models//345/260/217/346/243/222/350/277/233/344/275/215/345/212/240.md +7 -0
  768. package/skills/chalk-teaching/models//345/260/217/346/243/222/351/200/200/344/275/215/345/207/217.md +6 -0
  769. package/skills/chalk-teaching/models//346/216/222/351/230/237/347/202/271/351/230/265.md +7 -0
  770. package/skills/chalk-teaching/models//346/227/266/351/227/264/346/225/260/350/275/264.md +6 -0
  771. package/skills/chalk-teaching/models//346/245/274/345/261/202/351/227/264/351/232/224/345/233/276.md +7 -0
  772. package/skills/chalk-teaching/models//347/240/264/345/215/201.md +7 -0
  773. package/skills/chalk-teaching/models//347/253/226/345/274/217/351/200/200/344/275/215.md +6 -0
  774. package/skills/chalk-teaching/models//347/272/277/346/256/265/345/233/276.md +7 -0
  775. package/skills/chalk-teaching/models-index.md +24 -0
  776. 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
  777. package/skills/chalk-teaching/references//350/257/264/346/230/216/346/226/207/344/273/266.md +102 -0
  778. package/skills/chalk-verify/SKILL.md +57 -0
  779. package/skills/chalk-verify/references//350/257/204/345/210/244/346/240/207/345/207/206.md +69 -0
  780. package/skills/cotutor-analyze/SKILL.md +106 -0
  781. package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +31 -0
  782. package/skills/cotutor-board/SKILL.md +373 -0
  783. package/skills/cotutor-board/references/README.md +38 -0
  784. package/skills/cotutor-board/references/canvas.md +68 -0
  785. package/skills/cotutor-board/references/choice.md +55 -0
  786. package/skills/cotutor-board/references/code.md +46 -0
  787. package/skills/cotutor-board/references/image.md +52 -0
  788. package/skills/cotutor-board/references/lecture.md +69 -0
  789. package/skills/cotutor-board/references/paint.md +77 -0
  790. package/skills/cotutor-board/references/photo.md +61 -0
  791. package/skills/cotutor-board/references/read.md +51 -0
  792. package/skills/cotutor-board/references/text.md +69 -0
  793. package/skills/cotutor-board/references/tianzige.md +78 -0
  794. package/skills/cotutor-board/references/word.md +91 -0
  795. package/skills/cotutor-home/SKILL.md +169 -0
  796. package/skills/cotutor-home/references/dictation.md +97 -0
  797. package/skills/cotutor-home/references/tutor.md +148 -0
  798. package/skills/cotutor-home/references//345/221/275/344/273/244.md +21 -0
  799. package/skills/cotutor-home/references//351/246/226/351/241/265/350/257/255/346/263/225.md +142 -0
  800. package/skills/cotutor-tune/SKILL.md +147 -0
  801. package/skills/cotutor-tune/references//345/255/227/346/256/265.md +50 -0
  802. package/skills/cotutor-tutor/SKILL.md +261 -0
  803. package/skills/cotutor-tutor/references//344/270/212/344/270/213/346/226/207/345/214/205.md +78 -0
  804. package/themes/default/kid.css +86 -0
  805. package/themes/default/theme.json +26 -0
  806. package/agents/chinese-tutor.md +0 -67
  807. package/agents/homework-tutor.md +0 -17
  808. package/agents/math-tutor.md +0 -68
  809. package/agents/planner.md +0 -18
  810. package/agents/reading-tutor.md +0 -65
  811. package/agents/scene-maker.md +0 -41
  812. package/dist/cards/canvas.d.ts +0 -22
  813. package/dist/cards/canvas.js +0 -65
  814. package/dist/cards/fill.d.ts +0 -14
  815. package/dist/cards/fill.js +0 -64
  816. package/dist/cards/index.d.ts +0 -48
  817. package/dist/cards/index.js +0 -115
  818. package/dist/cards/kind.js +0 -7
  819. package/dist/cards/scene.d.ts +0 -24
  820. package/dist/cards/scene.js +0 -67
  821. package/dist/cards/text.d.ts +0 -18
  822. package/dist/cards/text.js +0 -41
  823. package/dist/cli/doctor.js +0 -355
  824. package/dist/cli/init.js +0 -116
  825. package/dist/cli/main.js +0 -243
  826. package/dist/cli/serve.js +0 -56
  827. package/dist/cli/skeleton.d.ts +0 -39
  828. package/dist/cli/skeleton.js +0 -184
  829. package/dist/cli/skills.d.ts +0 -40
  830. package/dist/cli/skills.js +0 -170
  831. package/dist/cli/workspace.d.ts +0 -69
  832. package/dist/lib/agent-file.d.ts +0 -10
  833. package/dist/lib/agent-file.js +0 -16
  834. package/dist/lib/board.d.ts +0 -15
  835. package/dist/lib/board.js +0 -107
  836. package/dist/lib/context-pack.js +0 -55
  837. package/dist/lib/conversation.js +0 -88
  838. package/dist/lib/kid-board.d.ts +0 -148
  839. package/dist/lib/kid-board.js +0 -294
  840. package/dist/lib/kid-view.d.ts +0 -63
  841. package/dist/lib/kid-view.js +0 -93
  842. package/dist/lib/ledger.d.ts +0 -29
  843. package/dist/lib/run-plan.d.ts +0 -30
  844. package/dist/lib/run-plan.js +0 -32
  845. package/dist/lib/sections.d.ts +0 -12
  846. package/dist/lib/sections.js +0 -151
  847. package/dist/lib/stream.d.ts +0 -15
  848. package/dist/lib/stream.js +0 -69
  849. package/dist/lib/transcript.d.ts +0 -36
  850. package/dist/lib/transcript.js +0 -95
  851. package/dist/server/app.d.ts +0 -74
  852. package/dist/server/app.js +0 -406
  853. package/dist/server/kid-page.d.ts +0 -1
  854. package/dist/server/kid-page.js +0 -768
  855. package/dist/server/mock.js +0 -403
  856. package/dist/server/parent-page.d.ts +0 -8
  857. package/dist/server/parent-page.js +0 -393
  858. package/dist/server/runner.d.ts +0 -64
  859. package/dist/server/runner.js +0 -277
  860. package/dist/server/scene-props.d.ts +0 -16
  861. package/dist/server/scene-props.js +0 -39
  862. package/dist/server/store.d.ts +0 -43
  863. package/dist/server/store.js +0 -210
  864. package/dist/server/tts.d.ts +0 -51
  865. package/dist/server/tts.js +0 -99
  866. /package/dist/{cli → app/cli}/cert.d.ts +0 -0
  867. /package/dist/{cli → app/cli}/main.d.ts +0 -0
  868. /package/dist/{cards → board/cards}/choice.d.ts +0 -0
  869. /package/dist/{cards → board/cards}/code.d.ts +0 -0
  870. /package/dist/{cards → board/cards}/image.d.ts +0 -0
  871. /package/dist/{cards → board/cards}/read.d.ts +0 -0
@@ -0,0 +1,100 @@
1
+ /**
2
+ * 小课堂的纯函数:服务端(课长、上下文包 lecture: 的每句起点、画的地方盖着什么)与舞台包(播放器)共用。
3
+ *
4
+ * 课包的时钟、几何、圈住了什么(这里拿来说画的地方盖着什么)都在 src/chalk(纯计算,不带 React,服务端能 import):一段 = 一步,段长 = max(画, 配音),
5
+ * 课的 0 毫秒对着 SVG 的 START_MS;笔画按配音拉伸,和 buildAnimatedSvg 画出来的同一份时间。这里用小课堂的名字转出来
6
+ * (视频也有时钟,videoClock),外加小课堂自己的:时间怎么写、上下文包的每句、老师放的那一段、视频的 lecture.md。
7
+ */
8
+ import { type LessonPicture } from '../chalk/index.ts';
9
+ import type { LessonClock, LessonSegment } from '../chalk/index.ts';
10
+ export { lessonClock as lectureClock, clockAt as lectureAt, START_MS as DRAW_START_MS } from '../chalk/index.ts';
11
+ export type { ChalkSkeleton as LectureSkeleton, ChalkStep as LectureStep, ChalkBlock as LectureBlock, ChalkGroup as LectureGroup, LessonPicture as LecturePicture } from '../chalk/index.ts';
12
+ /** 小课堂的时钟:课包的(src/chalk 的 lessonClock)或视频的(videoClock,没有画面元素) */
13
+ export type LectureClock = LessonClock;
14
+ export type LectureSegment = LessonSegment;
15
+ /** 毫秒 → 「分:秒」;一小时以上「时:分:秒」 */
16
+ export declare function clockLabel(ms: number): string;
17
+ /** 上下文包 lecture.lines:每段一句「0:18 讲稿」 */
18
+ export declare function lectureLines(clock: Pick<LectureClock, 'segments'>): string[];
19
+ /** 换了 src 声音迟迟不出来,等多久就不等了,按墙上的钟走(毫秒) */
20
+ export declare const VOICE_STALL_MS = 1500;
21
+ /**
22
+ * 放着的时候时钟下一刻走到哪(课包):这一段的配音在放,跟着配音走——
23
+ * 「段起点 + 配音放到哪」,声音还没出来就停在原地等(不往回退);等过 VOICE_STALL_MS、配音放完了、没在放配音,按墙上的钟走 dt。
24
+ * voice:正在放的是第几段的配音、放到哪(毫秒)、位置多久没动了;没在放 = null。
25
+ */
26
+ export declare function lectureNext(clock: Pick<LectureClock, 'segments' | 'total'>, cur: number, dt: number, voice: {
27
+ index: number;
28
+ posMs: number;
29
+ stalledMs: number;
30
+ } | null): number;
31
+ /** 一处画:课里的时刻 + 几笔(课包画面坐标,即 scene.json 的坐标系;视频是视频自己的像素坐标) */
32
+ export interface LectureMark {
33
+ atMs: number;
34
+ strokes: [number, number][][];
35
+ }
36
+ /** 一堂课最多画几处(播放器与路由都拦):一处一张截图,和孩子拍的照片一共不过 9 张 */
37
+ export declare const MARK_MAX = 6;
38
+ /** 一处最多几笔、一共几个点;一笔的点抽到 MARK_STROKE_POINTS 以内 */
39
+ export declare const MARK_MAX_STROKES = 60;
40
+ export declare const MARK_MAX_POINTS = 1200;
41
+ export declare const MARK_STROKE_POINTS = 300;
42
+ /** 「0:26 画的,那时在讲『…』」:一处画给老师、家长的那段话的头 */
43
+ export declare function markHead(clock: LectureClock, atMs: number): string;
44
+ /**
45
+ * 几笔 → 给 src/chalk circleHits 的一圈:所有点的凸包(圈了一圈就是那一圈,没封口的也合上);
46
+ * 太细的(划一道、点一下)用外框,各边放宽到 MIN_RING。没有点 = []。
47
+ */
48
+ export declare function inkRing(strokes: readonly (readonly [number, number][])[]): [number, number][];
49
+ /**
50
+ * 画的地方盖着什么(只给课包,老师对着截图时的提示,用课里的叫法):「画的地方盖着:散的 3 根小棒;文字『3』」/「画在文字『3』旁边」/
51
+ * 「画的地方那时还没画东西」。认的是 src/chalk 的 circleHits(分组 > 命中块 > 带 label 的元素 > 文字 > 没字的按第几步、什么、颜色归堆),圈是 inkRing。
52
+ */
53
+ export declare function inkHint(clock: LectureClock, mark: LectureMark, picture?: LessonPicture): {
54
+ text: string;
55
+ ids: string[];
56
+ };
57
+ /** 一处画说成一段话(不带截图那半):「0:26 画的,那时在讲『…』;画的地方盖着:…」 */
58
+ export declare function describeMark(clock: LectureClock, mark: LectureMark, picture?: LessonPicture): {
59
+ text: string;
60
+ ids: string[];
61
+ };
62
+ /** 「分:秒」「时:分:秒」→ 毫秒;认不出来 null */
63
+ export declare function parseClock(s: string): number | null;
64
+ /**
65
+ * 卡上写的一段 → 真放的起止(毫秒)。lines: 里的时间是段起点取整到秒,老师照抄的「0:19」其实是 19.4 秒那段的开头:
66
+ * 起止落在某个段界前后一秒内,就对齐到那个段界(不多放前一段的尾巴、不切掉这一段的末字)。
67
+ * 不写止 = 放到起点所在那一段的末尾;都不写 = 整堂课。越界夹到课里;止不在起之后 = null。
68
+ */
69
+ export declare function lectureRange(clock: Pick<LectureClock, 'segments' | 'total'>, from: number | undefined, to: number | undefined): {
70
+ start: number;
71
+ end: number;
72
+ } | null;
73
+ export declare const LECTURE_FILE = "lecture.md";
74
+ export declare const LECTURE_VIDEO = "video.mp4";
75
+ export interface LectureDocIssue {
76
+ level: 'fix' | 'note';
77
+ text: string;
78
+ line?: number;
79
+ }
80
+ export interface LectureDoc {
81
+ title: string;
82
+ subject: string | null;
83
+ /** 一句一条:在视频里的起点(毫秒)与原话 */
84
+ chapters: {
85
+ start: number;
86
+ line: string;
87
+ at: number;
88
+ }[];
89
+ issues: LectureDocIssue[];
90
+ }
91
+ /**
92
+ * lecture.md:frontmatter(subject 可写)+ `# 标题` + 一行一句「分:秒 原话」(这一句在视频里的起点)。
93
+ * 别的行不认(给人看的话写在注释里);永不抛,问题带行号。时长不在这里查(要读 mp4),由调用方对。
94
+ */
95
+ export declare function parseLectureDoc(md: string): LectureDoc;
96
+ /** 视频的时钟:一句一段(起点到下一句的起点,最后一句到视频末尾);没有画面元素,SVG 那几个数都是 0 */
97
+ export declare function videoClock(chapters: readonly {
98
+ start: number;
99
+ line: string;
100
+ }[], totalMs: number): LectureClock;
@@ -0,0 +1,204 @@
1
+ /**
2
+ * 小课堂的纯函数:服务端(课长、上下文包 lecture: 的每句起点、画的地方盖着什么)与舞台包(播放器)共用。
3
+ *
4
+ * 课包的时钟、几何、圈住了什么(这里拿来说画的地方盖着什么)都在 src/chalk(纯计算,不带 React,服务端能 import):一段 = 一步,段长 = max(画, 配音),
5
+ * 课的 0 毫秒对着 SVG 的 START_MS;笔画按配音拉伸,和 buildAnimatedSvg 画出来的同一份时间。这里用小课堂的名字转出来
6
+ * (视频也有时钟,videoClock),外加小课堂自己的:时间怎么写、上下文包的每句、老师放的那一段、视频的 lecture.md。
7
+ */
8
+ import { circleHits, clockAt, hitPhrase } from "../chalk/index.js";
9
+ export { lessonClock as lectureClock, clockAt as lectureAt, START_MS as DRAW_START_MS } from "../chalk/index.js";
10
+ /** 毫秒 → 「分:秒」;一小时以上「时:分:秒」 */
11
+ export function clockLabel(ms) {
12
+ const s = Math.max(0, Math.floor(ms / 1000));
13
+ const h = Math.floor(s / 3600);
14
+ const m = Math.floor((s % 3600) / 60);
15
+ const ss = String(s % 60).padStart(2, '0');
16
+ return h ? `${h}:${String(m).padStart(2, '0')}:${ss}` : `${m}:${ss}`;
17
+ }
18
+ /** 上下文包 lecture.lines:每段一句「0:18 讲稿」 */
19
+ export function lectureLines(clock) {
20
+ return clock.segments.map((s) => `${clockLabel(s.start)} ${s.line.trim()}`);
21
+ }
22
+ /** 换了 src 声音迟迟不出来,等多久就不等了,按墙上的钟走(毫秒) */
23
+ export const VOICE_STALL_MS = 1500;
24
+ /**
25
+ * 放着的时候时钟下一刻走到哪(课包):这一段的配音在放,跟着配音走——
26
+ * 「段起点 + 配音放到哪」,声音还没出来就停在原地等(不往回退);等过 VOICE_STALL_MS、配音放完了、没在放配音,按墙上的钟走 dt。
27
+ * voice:正在放的是第几段的配音、放到哪(毫秒)、位置多久没动了;没在放 = null。
28
+ */
29
+ export function lectureNext(clock, cur, dt, voice) {
30
+ const wall = Math.min(clock.total, cur + dt);
31
+ if (!voice)
32
+ return wall;
33
+ const s = clock.segments[voice.index];
34
+ if (!s || s.audioMs === null || voice.posMs >= s.audioMs || voice.stalledMs > VOICE_STALL_MS)
35
+ return wall;
36
+ // 声音是别的段的(刚拖过、刚换段):不跟
37
+ if (cur < s.start || cur >= s.start + s.len)
38
+ return wall;
39
+ return Math.min(clock.total, Math.max(cur, s.start + voice.posMs));
40
+ }
41
+ /** 一堂课最多画几处(播放器与路由都拦):一处一张截图,和孩子拍的照片一共不过 9 张 */
42
+ export const MARK_MAX = 6;
43
+ /** 一处最多几笔、一共几个点;一笔的点抽到 MARK_STROKE_POINTS 以内 */
44
+ export const MARK_MAX_STROKES = 60;
45
+ export const MARK_MAX_POINTS = 1200;
46
+ export const MARK_STROKE_POINTS = 300;
47
+ /** 「0:26 画的,那时在讲『…』」:一处画给老师、家长的那段话的头 */
48
+ export function markHead(clock, atMs) {
49
+ const line = clock.segments[clockAt(clock, atMs).index]?.line.trim() ?? '';
50
+ return `${clockLabel(atMs)} 画的${line ? `,那时在讲『${line}』` : ''}`;
51
+ }
52
+ /** 太细的一处(一条线、一个点)给 circleHits 的框至少多宽(课包坐标) */
53
+ const MIN_RING = 24;
54
+ /**
55
+ * 几笔 → 给 src/chalk circleHits 的一圈:所有点的凸包(圈了一圈就是那一圈,没封口的也合上);
56
+ * 太细的(划一道、点一下)用外框,各边放宽到 MIN_RING。没有点 = []。
57
+ */
58
+ export function inkRing(strokes) {
59
+ const pts = strokes.flat().slice().sort((a, b) => a[0] - b[0] || a[1] - b[1]);
60
+ if (!pts.length)
61
+ return [];
62
+ // 凸包(Andrew 单调链)
63
+ const cross = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
64
+ const half = (list) => {
65
+ const h = [];
66
+ for (const p of list) {
67
+ while (h.length >= 2 && cross(h[h.length - 2], h[h.length - 1], p) <= 0)
68
+ h.pop();
69
+ h.push(p);
70
+ }
71
+ h.pop();
72
+ return h;
73
+ };
74
+ const hull = [...half(pts), ...half(pts.slice().reverse())];
75
+ const xs = pts.map((p) => p[0]), ys = pts.map((p) => p[1]);
76
+ const [x0, x1, y0, y1] = [Math.min(...xs), Math.max(...xs), Math.min(...ys), Math.max(...ys)];
77
+ if (hull.length >= 3 && x1 - x0 >= MIN_RING && y1 - y0 >= MIN_RING)
78
+ return hull;
79
+ const cx = (x0 + x1) / 2, cy = (y0 + y1) / 2, hw = Math.max(x1 - x0, MIN_RING) / 2, hh = Math.max(y1 - y0, MIN_RING) / 2;
80
+ return [[cx - hw, cy - hh], [cx + hw, cy - hh], [cx + hw, cy + hh], [cx - hw, cy + hh]];
81
+ }
82
+ /**
83
+ * 画的地方盖着什么(只给课包,老师对着截图时的提示,用课里的叫法):「画的地方盖着:散的 3 根小棒;文字『3』」/「画在文字『3』旁边」/
84
+ * 「画的地方那时还没画东西」。认的是 src/chalk 的 circleHits(分组 > 命中块 > 带 label 的元素 > 文字 > 没字的按第几步、什么、颜色归堆),圈是 inkRing。
85
+ */
86
+ export function inkHint(clock, mark, picture = {}) {
87
+ const ring = inkRing(mark.strokes);
88
+ if (!ring.length)
89
+ return { text: '', ids: [] };
90
+ const r = circleHits(clock, mark.atMs, ring, picture);
91
+ const say = (h) => hitPhrase(h).replace('(圈住了其中', '(盖着其中');
92
+ const text = r.kind === 'hit' ? `画的地方盖着:${r.hits.map(say).join(';')}` : r.kind === 'near' && r.near ? `画在${say(r.near)}旁边` : r.kind === 'empty' ? '画的地方那时还没画东西' : '';
93
+ return { text, ids: r.ids };
94
+ }
95
+ /** 一处画说成一段话(不带截图那半):「0:26 画的,那时在讲『…』;画的地方盖着:…」 */
96
+ export function describeMark(clock, mark, picture = {}) {
97
+ const h = inkHint(clock, mark, picture);
98
+ return { text: `${markHead(clock, mark.atMs)}${h.text ? `;${h.text}` : ''}`, ids: h.ids };
99
+ }
100
+ // ---- 老师放课里的一段:lecture 卡写「<课包 id> 0:19-0:30」 ----
101
+ /** 「分:秒」「时:分:秒」→ 毫秒;认不出来 null */
102
+ export function parseClock(s) {
103
+ const m = /^(?:(\d{1,2}):)?(\d{1,3}):(\d{2})$/.exec(s.trim());
104
+ if (!m)
105
+ return null;
106
+ const [h, mm, ss] = [Number(m[1] ?? 0), Number(m[2]), Number(m[3])];
107
+ if (ss >= 60 || (m[1] !== undefined && mm >= 60))
108
+ return null;
109
+ return ((h * 60 + mm) * 60 + ss) * 1000;
110
+ }
111
+ /**
112
+ * 卡上写的一段 → 真放的起止(毫秒)。lines: 里的时间是段起点取整到秒,老师照抄的「0:19」其实是 19.4 秒那段的开头:
113
+ * 起止落在某个段界前后一秒内,就对齐到那个段界(不多放前一段的尾巴、不切掉这一段的末字)。
114
+ * 不写止 = 放到起点所在那一段的末尾;都不写 = 整堂课。越界夹到课里;止不在起之后 = null。
115
+ */
116
+ export function lectureRange(clock, from, to) {
117
+ if (!clock.segments.length)
118
+ return null;
119
+ const bounds = [...clock.segments.map((s) => s.start), clock.total];
120
+ const snap = (ms) => bounds.find((b) => b >= ms && b - ms < 1000) ?? ms;
121
+ const start = from === undefined ? 0 : Math.min(snap(from), clock.total);
122
+ let end;
123
+ if (to !== undefined)
124
+ end = Math.min(snap(to), clock.total);
125
+ else if (from === undefined)
126
+ end = clock.total;
127
+ else {
128
+ const i = clockAt(clock, start).index;
129
+ end = clock.segments[i].start + clock.segments[i].len;
130
+ }
131
+ return end > start ? { start, end } : null;
132
+ }
133
+ // ---- 视频来源(第 4 步):lectures/<id>/lecture.md + video.mp4 ----
134
+ export const LECTURE_FILE = 'lecture.md';
135
+ export const LECTURE_VIDEO = 'video.mp4';
136
+ /**
137
+ * lecture.md:frontmatter(subject 可写)+ `# 标题` + 一行一句「分:秒 原话」(这一句在视频里的起点)。
138
+ * 别的行不认(给人看的话写在注释里);永不抛,问题带行号。时长不在这里查(要读 mp4),由调用方对。
139
+ */
140
+ export function parseLectureDoc(md) {
141
+ const lines = md.replace(/<!--[\s\S]*?-->/g, (c) => '\n'.repeat(c.split('\n').length - 1)).split(/\r?\n/);
142
+ const issues = [];
143
+ let start = 0;
144
+ let subject = null;
145
+ if (/^---\s*$/.test(lines[0] ?? '')) {
146
+ const close = lines.findIndex((l, i) => i > 0 && /^---\s*$/.test(l));
147
+ if (close < 0)
148
+ issues.push({ level: 'fix', line: 1, text: 'frontmatter 没闭合:key: value 那几行之后单独一行写 ---' });
149
+ else {
150
+ for (let i = 1; i < close; i++) {
151
+ const m = /^([A-Za-z][\w-]*):\s*(.*)$/.exec(lines[i]);
152
+ if (m?.[1] === 'subject' && m[2].trim())
153
+ subject = m[2].trim();
154
+ else if (lines[i].trim())
155
+ issues.push({ level: 'note', line: i + 1, text: `frontmatter 只认 subject:${lines[i].trim()}` });
156
+ }
157
+ start = close + 1;
158
+ }
159
+ }
160
+ let title = '';
161
+ const chapters = [];
162
+ for (let i = start; i < lines.length; i++) {
163
+ const l = lines[i].trim();
164
+ if (!l)
165
+ continue;
166
+ const h = /^#\s+(.+)$/.exec(l);
167
+ if (h && !title) {
168
+ title = h[1].trim();
169
+ continue;
170
+ }
171
+ const m = /^((?:\d{1,2}:)?\d{1,3}:\d{2})\s+(.+)$/.exec(l);
172
+ const ms = m ? parseClock(m[1]) : null;
173
+ if (m && ms !== null) {
174
+ const prev = chapters[chapters.length - 1];
175
+ if (prev && ms <= prev.start)
176
+ issues.push({ level: 'fix', line: i + 1, text: `时间要一句比一句晚:${m[1]} 不晚于上一句的 ${clockLabel(prev.start)}` });
177
+ else
178
+ chapters.push({ start: ms, line: m[2].trim(), at: i + 1 });
179
+ }
180
+ else
181
+ issues.push({ level: 'note', line: i + 1, text: `这行不认(一行一句写「分:秒 原话」,给人看的话写在 <!-- --> 里):${l.slice(0, 30)}` });
182
+ }
183
+ if (!title)
184
+ issues.push({ level: 'fix', line: start + 1, text: '要有一行 # 标题(孩子首页按钮上、老师上下文包里的课名)' });
185
+ if (!chapters.length)
186
+ issues.push({ level: 'fix', text: '一句都没有:一行一句写「分:秒 原话」,老师靠它知道课里讲了什么、孩子停在哪' });
187
+ else if (chapters[0].start !== 0)
188
+ issues.push({ level: 'note', line: chapters[0].at, text: `第一句从 ${clockLabel(chapters[0].start)} 起,前面那段老师不知道在讲什么` });
189
+ return { title, subject, chapters, issues };
190
+ }
191
+ /** 视频的时钟:一句一段(起点到下一句的起点,最后一句到视频末尾);没有画面元素,SVG 那几个数都是 0 */
192
+ export function videoClock(chapters, totalMs) {
193
+ const cs = chapters.filter((c) => c.start < totalMs);
194
+ const segments = cs.map((c, i) => {
195
+ const end = i + 1 < cs.length ? cs[i + 1].start : totalMs;
196
+ return { index: i, start: c.start, len: Math.max(1, end - c.start), drawStart: 0, drawEnd: 0, audioMs: null, line: c.line };
197
+ });
198
+ // 第一句不从 0 起:前面补一段没有话的
199
+ if (segments.length && segments[0].start > 0) {
200
+ segments.unshift({ index: 0, start: 0, len: segments[0].start, drawStart: 0, drawEnd: 0, audioMs: null, line: '' });
201
+ segments.forEach((s, i) => { s.index = i; });
202
+ }
203
+ return { skeletons: [], segments, total: segments.length ? totalMs : 0, elements: new Map() };
204
+ }
@@ -0,0 +1,20 @@
1
+ import type { Workspace } from '../schema/index.ts';
2
+ import { type CanvasState } from './cards/canvas.ts';
3
+ import type { ConversationMessage } from '../schema/index.ts';
4
+ /** 纸的名字:话题 id(<HHMM>-<n>),或 new(话题还没有) */
5
+ export declare const PAPER_KEY_RE: RegExp;
6
+ /** 只交了画、没说话时这条消息的字(同「(拍了一张)」;孩子端不把它当孩子说的话,board/presentation.ts 的 DRAW_ONLY) */
7
+ export declare const DRAW_ONLY_TEXT = "(\u753B\u4E86\u4E00\u5F20,\u6CA1\u8BF4\u8BDD)";
8
+ export type PaperState = Pick<CanvasState, 'ink' | 'cleared'>;
9
+ /** 读一张纸;没有、坏了都是空白的 */
10
+ export declare function readPaper(ws: Workspace, tutor: string, date: string, key: string): Promise<PaperState>;
11
+ /** 存一张纸(整份),另记一行实录 */
12
+ export declare function writePaper(ws: Workspace, tutor: string, date: string, key: string, state: PaperState, now: Date): Promise<void>;
13
+ /** 新话题的第一条发出去了:话题还没有时画的那张(new)归这个话题;这个话题已经有一张就不动 */
14
+ export declare function adoptPaper(ws: Workspace, tutor: string, date: string, thread: string): Promise<void>;
15
+ /** 删一张纸(测试、清场用) */
16
+ export declare function dropPaper(ws: Workspace, tutor: string, date: string, key: string): Promise<void>;
17
+ /** 交画:按纸上的笔迹算这条消息记的摘要(几笔、各颜色几笔、画了多久、清掉的那几版的图) */
18
+ export declare function paperDrawing(state: PaperState, image: string): NonNullable<ConversationMessage['drawing']>;
19
+ /** 上下文包 drawing: 那一句;first = 这张画在 photos 里是第几张(1 起),清掉的那几版紧跟在后面 */
20
+ export declare function drawingPackLine(d: NonNullable<ConversationMessage['drawing']>, first: number): string;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * 左栏的纸:孩子在实时老师页左栏点「画板」打开的那张,一个话题一张,一直能改,关了不丢。
3
+ * 存 conversations/<老师>/<日期>.<话题>.paper.json(状态同画板卡:笔迹 + 清空前存的那几版),每次存另记一行 .paper.jsonl(以后录像现画用);
4
+ * 话题还没有(新话题、空板)时叫 new,这个话题的第一条发出去就改名成话题 id(adoptPaper)。删话题按 <日期>.<话题>.* 一起删。
5
+ * 「给老师看」时孩子端先把导出的图传进 captures/,消息带 {drawing: {key, image}};这里按纸上的笔迹算摘要(几笔、各颜色、多久、清掉的那几版),记进消息。
6
+ */
7
+ import { appendFile, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
8
+ import { existsSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { CanvasStateSchema } from "./cards/canvas.js";
11
+ import { canvasStrokes, canvasSummary, canvasMinutesText } from "./canvas-chat.js";
12
+ /** 纸的名字:话题 id(<HHMM>-<n>),或 new(话题还没有) */
13
+ export const PAPER_KEY_RE = /^(?:new|\d{4}-\d+)$/;
14
+ /** 只交了画、没说话时这条消息的字(同「(拍了一张)」;孩子端不把它当孩子说的话,board/presentation.ts 的 DRAW_ONLY) */
15
+ export const DRAW_ONLY_TEXT = '(画了一张,没说话)';
16
+ const paperFile = (ws, tutor, date, key, ext) => join(ws.dirs.conversations, tutor, `${date}.${key}.paper.${ext}`);
17
+ /** 读一张纸;没有、坏了都是空白的 */
18
+ export async function readPaper(ws, tutor, date, key) {
19
+ if (!PAPER_KEY_RE.test(key))
20
+ return { ink: [] };
21
+ try {
22
+ const r = CanvasStateSchema.safeParse(JSON.parse(await readFile(paperFile(ws, tutor, date, key, 'json'), 'utf8')));
23
+ if (r.success)
24
+ return { ink: r.data.ink, ...(r.data.cleared?.length ? { cleared: r.data.cleared } : {}) };
25
+ }
26
+ catch { /* 没有 */ }
27
+ return { ink: [] };
28
+ }
29
+ /** 存一张纸(整份),另记一行实录 */
30
+ export async function writePaper(ws, tutor, date, key, state, now) {
31
+ const st = { ink: state.ink, ...(state.cleared?.length ? { cleared: state.cleared } : {}) };
32
+ await mkdir(join(ws.dirs.conversations, tutor), { recursive: true });
33
+ await writeFile(paperFile(ws, tutor, date, key, 'json'), JSON.stringify(st));
34
+ await appendFile(paperFile(ws, tutor, date, key, 'jsonl'), `${JSON.stringify({ at: now.getTime(), k: 'paper', state: st })}\n`).catch(() => { });
35
+ }
36
+ /** 新话题的第一条发出去了:话题还没有时画的那张(new)归这个话题;这个话题已经有一张就不动 */
37
+ export async function adoptPaper(ws, tutor, date, thread) {
38
+ if (!PAPER_KEY_RE.test(thread) || thread === 'new')
39
+ return;
40
+ const from = paperFile(ws, tutor, date, 'new', 'json');
41
+ if (!existsSync(from) || existsSync(paperFile(ws, tutor, date, thread, 'json')))
42
+ return;
43
+ await rename(from, paperFile(ws, tutor, date, thread, 'json')).catch(() => { });
44
+ await rename(paperFile(ws, tutor, date, 'new', 'jsonl'), paperFile(ws, tutor, date, thread, 'jsonl')).catch(() => { });
45
+ }
46
+ /** 删一张纸(测试、清场用) */
47
+ export async function dropPaper(ws, tutor, date, key) {
48
+ for (const ext of ['json', 'jsonl'])
49
+ await rm(paperFile(ws, tutor, date, key, ext), { force: true });
50
+ }
51
+ /** 交画:按纸上的笔迹算这条消息记的摘要(几笔、各颜色几笔、画了多久、清掉的那几版的图) */
52
+ export function paperDrawing(state, image) {
53
+ const sum = canvasSummary(canvasStrokes(state.ink));
54
+ const cleared = state.cleared ?? [];
55
+ const named = sum.colors.filter((c) => c.name !== '别的颜色');
56
+ const starts = [...cleared.map((c) => c.from ?? c.at), ...(sum.firstAt !== null ? [sum.firstAt] : [])].filter((x) => x > 0);
57
+ const end = sum.lastAt ?? (cleared.length ? cleared[cleared.length - 1].at : null);
58
+ const imgs = cleared.flatMap((c) => (c.image ? [c.image] : []));
59
+ return {
60
+ image,
61
+ strokes: sum.strokes,
62
+ ...(named.length ? { colors: named.map((c) => `${c.name} ${c.strokes}`).join('、') } : {}),
63
+ ...(starts.length && end !== null ? { ms: Math.max(0, end - Math.min(...starts)) } : {}),
64
+ ...(imgs.length ? { cleared: imgs } : {}),
65
+ };
66
+ }
67
+ /** 上下文包 drawing: 那一句;first = 这张画在 photos 里是第几张(1 起),清掉的那几版紧跟在后面 */
68
+ export function drawingPackLine(d, first) {
69
+ const parts = [`孩子在纸上画的,photos 第 ${first} 张`, `画了 ${d.strokes} 笔${d.colors ? `(${d.colors})` : ''}`];
70
+ if (d.ms !== undefined)
71
+ parts.push(`画了${canvasMinutesText(d.ms)}`);
72
+ const n = d.cleared?.length ?? 0;
73
+ if (n)
74
+ parts.push(`清空重画过,清掉的那几版是 photos 第 ${n === 1 ? first + 1 : `${first + 1}–${first + n}`} 张`);
75
+ return parts.join(';');
76
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * 板书解析器:老师的回复正文(已剥掉「记账」段)→ 一节 BoardSection。
3
+ * 三条规则(见 docs/卡片协议.md):围栏 = 卡(标签第一个词是 kind),普通行 = 讲稿一句,第一个 H2 起是给家长的尾巴。
4
+ * 讲稿句里 [词] 是标注(落到第一张含这个词的卡,整节找,卡在前在后都行),[[名 参数]] 是对上一张卡的动作(cue)。
5
+ * partial 模式给流式用:没闭合的围栏和没换行结束的最后一行压着不算,下次整段重解析自然补上。
6
+ * 永不抛错:围栏没闭合当到文末,卡解析不出退成文字卡并记一句 warning。
7
+ * spans 是「这张卡 / 这句话是原文哪几行」,家长端「看原文」据此在原文旁边标出解析器怎么读的;孩子端的 BoardSection 不带它。
8
+ */
9
+ import { type CardPlace } from './cards/index.ts';
10
+ import { type BoardCard, type BoardCue, type BoardLine, type BoardSection, type Device } from './presentation.ts';
11
+ export interface ParseBoardOptions {
12
+ /** 文本还在长(流式):压住没闭合的围栏与没换行结束的最后一行 */
13
+ partial?: boolean;
14
+ /** 卡用在哪(缺省板书);首页文件同一个解析器,place = home */
15
+ place?: CardPlace;
16
+ /** 围栏行上写了排版修饰词(same)时,排出来的行是给哪个端的(layout.for);缺省平板横屏 */
17
+ device?: Device;
18
+ /** 实时的一轮:板是脑写的笔记与练习,末句的问话不补成提问卡(字幕上就是这句) */
19
+ live?: boolean;
20
+ }
21
+ /**
22
+ * 排版修饰词:写在围栏标签里种类后面,哪种卡都认,解析器先摘掉再按种类解析——
23
+ * `same` 和上一张并排(没写 = 孩子端按卡的宽度排,board/presentation.ts 的 rowsFor)、`tint=<底色槽>`、`look=<字形槽>`、`emoji=<一个>`。槽名没人对着主题查(解析器不认识主题),对不上的 CSS 落回缺省。
24
+ * 老师也写得出来:cotutor-board 技能不教,写了就当已定
25
+ */
26
+ export interface CardMods {
27
+ same?: true;
28
+ tint?: string;
29
+ look?: string;
30
+ emoji?: string;
31
+ }
32
+ export declare function splitMods(tag: string): {
33
+ rest: string;
34
+ mods: CardMods;
35
+ warnings: string[];
36
+ };
37
+ /** 解析提醒;line = 出问题的那一行(0 起,相对传进来的文本),没有行的就不带 */
38
+ export interface BoardWarning {
39
+ text: string;
40
+ line?: number;
41
+ /** 这张卡没照标签解析成(退了文字卡 / 代码卡) */
42
+ fallback?: boolean;
43
+ }
44
+ /** 行区间 [起, 止],含两端,0 起 */
45
+ export type LineSpan = [number, number];
46
+ export interface BoardSpans {
47
+ /** 与 section.cards 同序 */
48
+ cards: LineSpan[];
49
+ /** 与 section.lines 同序 */
50
+ lines: LineSpan[];
51
+ /** 第一个 H2 起到文末 */
52
+ tail: LineSpan | null;
53
+ /** 写成正文的工具调用(TOOL_OPEN 起到收尾行),不进板书 */
54
+ toolCalls: LineSpan[];
55
+ }
56
+ export interface ParsedBoard {
57
+ section: BoardSection;
58
+ /** 没解析成的卡等,家长视图转录里显示;孩子端不报 */
59
+ warnings: BoardWarning[];
60
+ /** 第一个 H2 起的尾巴(老师写的任何标题段,原文含标题行);没有 = 空串 */
61
+ tail: string;
62
+ spans: BoardSpans;
63
+ }
64
+ /** 讲稿一行的清洗:去掉老师不该写但常写的标题号、列表号、引用号、粗体号;整行的 HTML 注释不算话 */
65
+ export declare function cleanSpeech(line: string): string;
66
+ /** 一句讲稿交给嘴时要带的:[[play]] 到小课堂卡、热身的 echo / say、call(runner 的 line 事件、mock 的假嘴都用它) */
67
+ export declare function lineFlags(line: {
68
+ cues?: readonly BoardCue[];
69
+ echo?: BoardLine['echo'];
70
+ call?: true;
71
+ }, cards: readonly BoardCard[]): {
72
+ play?: true;
73
+ echo?: NonNullable<BoardLine['echo']>;
74
+ call?: true;
75
+ };
76
+ /** 这句的 [[play]] 锚着小课堂卡:念完放卡上那一段(实时时服务端在这句之后等孩子端放完再交讲稿,src/runtime/delivery/queue.ts) */
77
+ export declare function playsLecture(line: {
78
+ cues?: readonly BoardCue[];
79
+ }, cards: readonly BoardCard[]): boolean;
80
+ export declare function parseBoard(text: string, opts?: ParseBoardOptions): ParsedBoard;
81
+ /** 回复停在写成正文的工具调用上(后面只剩空行):老师在等工具的结果,这一轮其实没写完(runner 据此 resume 一次) */
82
+ export declare function endsWithToolCall(text: string): boolean;
83
+ /** 原文一行的角色:解析器把它当什么了 */
84
+ export type SourceRole =
85
+ /** 讲稿一句(念出来) */
86
+ 'say'
87
+ /** 卡的围栏(开头行 / 中间 / 结尾) */
88
+ | 'card'
89
+ /** 第一个 H2 起给家长的尾巴 */
90
+ | 'tail'
91
+ /** 被「## 记账」吃掉,不进板书 */
92
+ | 'section'
93
+ /** 空行 */
94
+ | 'blank'
95
+ /** 落在地上的行:清洗完是空的(整行注释等) */
96
+ | 'drop';
97
+ export interface SourceRow {
98
+ /** 0 起 */
99
+ line: number;
100
+ text: string;
101
+ role: SourceRole;
102
+ /** 右边那句「卡 2 · text formula」「讲稿 1 · 播」 */
103
+ label?: string;
104
+ /** role=card 时是第几张卡(0 起);role=say 时是第几句 */
105
+ index?: number;
106
+ /** 围栏开头那行 */
107
+ open?: boolean;
108
+ }
109
+ export interface AnnotatedSource {
110
+ rows: SourceRow[];
111
+ /** 行号换算成原文的 */
112
+ warnings: BoardWarning[];
113
+ section: BoardSection;
114
+ tail: string;
115
+ }
116
+ /**
117
+ * 家长端「看原文」用:把老师原文的每一行标上解析器怎么读的。
118
+ * 不另写一套解析——真跑 parseSections + parseBoard,再把它们的行号映回原文,所以永远不会和真解析漂开。
119
+ */
120
+ export declare function annotateSource(text: string, opts?: Pick<ParseBoardOptions, 'live'>): AnnotatedSource;