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,112 @@
1
+ import type { DictationWord } from '../../board/cards/index.ts';
2
+ import type { CharJudge, InkPoint } from './match.ts';
3
+ import type { PhotoItem } from './recognize.ts';
4
+ export declare const ID_RE: RegExp;
5
+ /** 擦掉的一笔:什么时候擦的(离开始多少毫秒,撤销、擦掉、点「给答案」清掉的都算) */
6
+ export interface InkGone {
7
+ t: number;
8
+ pts: InkPoint[];
9
+ }
10
+ /** 一个格里写的:留下来的笔,撤销 / 擦掉了几次;擦掉的笔另记在 gone(录像里在擦的那一刻消失;老数据没有) */
11
+ export interface CharInk {
12
+ strokes: InkPoint[][];
13
+ undos: number;
14
+ gone?: InkGone[];
15
+ /** 写之前点了「不会写,给答案」,看了笔顺照着描红写的 */
16
+ revealed?: boolean;
17
+ }
18
+ /** 一个词写的一遍 */
19
+ export interface Attempt {
20
+ at: string;
21
+ chars: CharInk[];
22
+ judges: CharJudge[];
23
+ }
24
+ /**
25
+ * 孩子做的事,录像按它排时间:
26
+ * 写的时候 show 出了这个词、say 老师念了一遍(n 第几遍)、again 点了再念、reveal 点了「给答案」(服务端记)、order 看了一遍笔顺、done 写好了这个字;
27
+ * 对答案时 strokeOrder 点开一个字逐笔看、rewrite 问了再写一遍点「好」、self 自己说「我想再写」。
28
+ * 录像要的:trace 给答案后换成照着写(看笔顺放完或落笔,老记录是点「我来写」)、open 点听写本上的一格回去改、close 从逐笔看 / 再写一遍回到对一对、
29
+ * view 屏幕多大(w、h,进页面与转屏)与写字格的档(pad,换档也记)、away / back 切到别处 / 回来。
30
+ */
31
+ export declare const EVENT_KINDS: readonly ["show", "say", "again", "reveal", "order", "done", "strokeOrder", "rewrite", "self", "trace", "open", "close", "view", "away", "back"];
32
+ export interface DictationEvent {
33
+ /** 服务端收到的时刻 */
34
+ at: string;
35
+ /** 孩子端的时刻:离这次听写开始(startedAt)多少毫秒,和笔迹的点同一个尺子;老数据没有 */
36
+ t?: number;
37
+ kind: (typeof EVENT_KINDS)[number];
38
+ word: number;
39
+ char?: number;
40
+ /** say 是第几遍 */
41
+ n?: number;
42
+ /** view:孩子屏幕的 CSS 尺寸 */
43
+ w?: number;
44
+ h?: number;
45
+ /** view:写字格的档(l 铺满 / m 500 / s 380);老数据没有,按 l */
46
+ pad?: 'l' | 'm' | 's';
47
+ }
48
+ export interface Session {
49
+ id: string;
50
+ /** 从哪份首页的第几张听写卡来的(首页 id 与听写卡的序号,0 起);拍照开始的 home = null、n = -1 */
51
+ home: string | null;
52
+ n: number;
53
+ /** 拍照开始的:哪张照片(dictation/photos/<photo>.jpg)、照片上认出的课名 */
54
+ photo?: string;
55
+ lesson?: string | null;
56
+ tutor: string | null;
57
+ /** 英文单词听写(一个单词一个四线三格,不逐字母比);汉字的不写 */
58
+ lang?: 'en';
59
+ words: DictationWord[];
60
+ startedAt: string;
61
+ /** 第一遍:一个词一项,还没写的 null */
62
+ first: (Attempt | null)[];
63
+ /** 交了、开始对答案的时刻;之后第一遍不能改 */
64
+ checkedAt: string | null;
65
+ /** 对答案时问了「这个再写一遍?」的词 */
66
+ asked: number[];
67
+ /** 再写的:一个词可以写几遍 */
68
+ rewrites: {
69
+ word: number;
70
+ self: boolean;
71
+ attempt: Attempt;
72
+ }[];
73
+ events: DictationEvent[];
74
+ doneAt: string | null;
75
+ }
76
+ export declare const rootOf: (wsRoot: string) => string;
77
+ export declare function writeSession(wsRoot: string, s: Session): Promise<void>;
78
+ export declare function readSession(wsRoot: string, id: string): Promise<Session | null>;
79
+ /** 全部听写,新的在前 */
80
+ export declare function listSessions(wsRoot: string): Promise<Session[]>;
81
+ /** 新 id:日期-时分;同一分钟已经有了(taken)加 -2、-3 */
82
+ export declare function newId(wsRoot: string, now: Date, taken?: (id: string) => boolean): string;
83
+ export declare function createSession(wsRoot: string, init: {
84
+ home: string | null;
85
+ n: number;
86
+ tutor: string | null;
87
+ words: DictationWord[];
88
+ photo?: string;
89
+ lesson?: string | null;
90
+ lang?: 'en';
91
+ }, now: Date): Promise<Session>;
92
+ export interface PhotoRecord {
93
+ id: string;
94
+ at: string;
95
+ /** running 正在认(items 是已经认出的)/ done 认完 / failed 没认成(error 说为什么,items 是失败前认出的) */
96
+ state: 'running' | 'done' | 'failed';
97
+ items: PhotoItem[];
98
+ lesson: string | null;
99
+ /** 正文全文:一行一个字符串,词之间空一格(孩子端能点着加词) */
100
+ full: string[];
101
+ error?: string;
102
+ model?: string;
103
+ ms?: number;
104
+ /** 认的是英文单词(英语老师卡上的拍照听写) */
105
+ lang?: 'en';
106
+ }
107
+ export declare const photosDir: (wsRoot: string) => string;
108
+ export declare const photoFile: (wsRoot: string, id: string) => string;
109
+ export declare function writePhotoRecord(wsRoot: string, r: PhotoRecord): Promise<void>;
110
+ export declare function readPhotoRecord(wsRoot: string, id: string): Promise<PhotoRecord | null>;
111
+ /** 存一张照片,开一份 running 的记录 */
112
+ export declare function createPhoto(wsRoot: string, data: Buffer, now: Date, lang?: 'en'): Promise<PhotoRecord>;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * 听写的存放:workspace 根的 dictation/<id>.json,一次听写一个文件;孩子的笔迹整个不进 git(目录里放一份 .gitignore)。
3
+ * id = 开始的时刻 YYYY-MM-DD-HHMM,同一分钟再开加 -2、-3。先写临时文件再换名,页面轮询读不到半截。
4
+ */
5
+ import { existsSync } from 'node:fs';
6
+ import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ export const ID_RE = /^\d{4}-\d{2}-\d{2}-\d{4}(?:-\d{1,2})?$/;
9
+ /**
10
+ * 孩子做的事,录像按它排时间:
11
+ * 写的时候 show 出了这个词、say 老师念了一遍(n 第几遍)、again 点了再念、reveal 点了「给答案」(服务端记)、order 看了一遍笔顺、done 写好了这个字;
12
+ * 对答案时 strokeOrder 点开一个字逐笔看、rewrite 问了再写一遍点「好」、self 自己说「我想再写」。
13
+ * 录像要的:trace 给答案后换成照着写(看笔顺放完或落笔,老记录是点「我来写」)、open 点听写本上的一格回去改、close 从逐笔看 / 再写一遍回到对一对、
14
+ * view 屏幕多大(w、h,进页面与转屏)与写字格的档(pad,换档也记)、away / back 切到别处 / 回来。
15
+ */
16
+ export const EVENT_KINDS = ['show', 'say', 'again', 'reveal', 'order', 'done', 'strokeOrder', 'rewrite', 'self', 'trace', 'open', 'close', 'view', 'away', 'back'];
17
+ export const rootOf = (wsRoot) => join(wsRoot, 'dictation');
18
+ const fileOf = (wsRoot, id) => join(rootOf(wsRoot), `${id}.json`);
19
+ const GITIGNORE = '# 听写的数据(孩子的笔迹)不进 git\n*\n';
20
+ async function ensureRoot(wsRoot) {
21
+ await mkdir(rootOf(wsRoot), { recursive: true });
22
+ const f = join(rootOf(wsRoot), '.gitignore');
23
+ if ((await readFile(f, 'utf8').catch(() => null)) !== GITIGNORE)
24
+ await writeFile(f, GITIGNORE);
25
+ }
26
+ let tmpSeq = 0;
27
+ export async function writeSession(wsRoot, s) {
28
+ await ensureRoot(wsRoot);
29
+ const file = fileOf(wsRoot, s.id);
30
+ // 临时文件各取各的名:同一次听写同时写两回(并发的请求)不能抢同一个临时文件
31
+ const tmp = `${file}.${process.pid}.${++tmpSeq}.tmp`;
32
+ await writeFile(tmp, `${JSON.stringify(s)}\n`);
33
+ await rename(tmp, file);
34
+ }
35
+ export async function readSession(wsRoot, id) {
36
+ if (!ID_RE.test(id))
37
+ return null;
38
+ try {
39
+ return JSON.parse(await readFile(fileOf(wsRoot, id), 'utf8'));
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ /** 全部听写,新的在前 */
46
+ export async function listSessions(wsRoot) {
47
+ const names = await readdir(rootOf(wsRoot)).catch(() => []);
48
+ const ids = names.filter((n) => n.endsWith('.json')).map((n) => n.slice(0, -5)).filter((id) => ID_RE.test(id));
49
+ const out = [];
50
+ for (const id of ids.sort().reverse()) {
51
+ const s = await readSession(wsRoot, id);
52
+ if (s)
53
+ out.push(s);
54
+ }
55
+ return out;
56
+ }
57
+ const p2 = (n) => String(n).padStart(2, '0');
58
+ /** 新 id:日期-时分;同一分钟已经有了(taken)加 -2、-3 */
59
+ export function newId(wsRoot, now, taken = (id) => existsSync(fileOf(wsRoot, id))) {
60
+ const base = `${now.getFullYear()}-${p2(now.getMonth() + 1)}-${p2(now.getDate())}-${p2(now.getHours())}${p2(now.getMinutes())}`;
61
+ let id = base;
62
+ for (let k = 2; taken(id); k++)
63
+ id = `${base}-${k}`;
64
+ return id;
65
+ }
66
+ export async function createSession(wsRoot, init, now) {
67
+ await ensureRoot(wsRoot);
68
+ const s = { id: newId(wsRoot, now), ...init, startedAt: now.toISOString(), first: init.words.map(() => null), checkedAt: null, asked: [], rewrites: [], events: [], doneAt: null };
69
+ await writeSession(wsRoot, s);
70
+ return s;
71
+ }
72
+ export const photosDir = (wsRoot) => join(rootOf(wsRoot), 'photos');
73
+ export const photoFile = (wsRoot, id) => join(photosDir(wsRoot), `${id}.jpg`);
74
+ export async function writePhotoRecord(wsRoot, r) {
75
+ const file = join(photosDir(wsRoot), `${r.id}.json`);
76
+ const tmp = `${file}.${process.pid}.tmp`;
77
+ await writeFile(tmp, `${JSON.stringify(r)}\n`);
78
+ await rename(tmp, file);
79
+ }
80
+ export async function readPhotoRecord(wsRoot, id) {
81
+ if (!ID_RE.test(id))
82
+ return null;
83
+ try {
84
+ return JSON.parse(await readFile(join(photosDir(wsRoot), `${id}.json`), 'utf8'));
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ }
90
+ /** 存一张照片,开一份 running 的记录 */
91
+ export async function createPhoto(wsRoot, data, now, lang) {
92
+ await ensureRoot(wsRoot);
93
+ await mkdir(photosDir(wsRoot), { recursive: true });
94
+ const id = newId(wsRoot, now, (x) => existsSync(photoFile(wsRoot, x)));
95
+ await writeFile(photoFile(wsRoot, id), data);
96
+ const r = { id, at: now.toISOString(), state: 'running', items: [], lesson: null, full: [], ...(lang ? { lang } : {}) };
97
+ await writePhotoRecord(wsRoot, r);
98
+ return r;
99
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 场景要的「看一张图」:一张图 + 提示词 + 模型 → 回的字(src/media/vision.ts 的 lookAt 就是这个样子;场景不认 media,由路由那层交进来)。
3
+ * 给 onDelta 就一块一块交出去(拍照认词边认边出);不给就整段收完再回。
4
+ */
5
+ export type Seen = {
6
+ ok: true;
7
+ text: string;
8
+ ms: number;
9
+ } | {
10
+ ok: false;
11
+ error: string;
12
+ ms: number;
13
+ };
14
+ export type Look = (o: {
15
+ image: {
16
+ data: Buffer;
17
+ mime: string;
18
+ };
19
+ prompt: string;
20
+ model: string;
21
+ params?: Record<string, unknown>;
22
+ timeoutMs: number;
23
+ env?: NodeJS.ProcessEnv;
24
+ endpoint?: string;
25
+ onDelta?: (text: string) => void;
26
+ }) => Promise<Seen>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ import type { BoardSection } from '../../board/presentation.ts';
2
+ import { type CotutorConfig } from '../../schema/index.ts';
3
+ /** 画图卡要的 workspace 那几样:对话目录(卡的资产落在这)、根(给孩子端的相对路径)、画图的配置;传整个 workspace 也行 */
4
+ export interface PaintSpace {
5
+ root: string;
6
+ dirs: {
7
+ conversations: string;
8
+ };
9
+ config: Pick<CotutorConfig, 'paint'>;
10
+ }
11
+ export type Drawn = ({
12
+ ok: true;
13
+ data: Buffer;
14
+ model: string;
15
+ } | {
16
+ ok: false;
17
+ error: string;
18
+ }) & {
19
+ ms: number;
20
+ };
21
+ /** 画一张(src/media/draw.ts 的 makeDraw 就是这个样子;场景不认 media,由 runner 交进来;测试与 mock 给假的) */
22
+ export type Draw = (job: {
23
+ prompt: string;
24
+ model: string;
25
+ size: string;
26
+ negative?: string;
27
+ }) => Promise<Drawn>;
28
+ export declare const PAINT_PNG = "paint.png";
29
+ export declare const PAINT_JSON = "paint.json";
30
+ /** 「在画」超过这么久还没落成(服务重起过、进程被杀),当没画成 */
31
+ export declare const PAINT_STALE_MS: number;
32
+ export type PaintRecord = {
33
+ state: 'drawing';
34
+ at: string;
35
+ prompt: string;
36
+ model: string;
37
+ negative?: string;
38
+ } | {
39
+ state: 'done';
40
+ at: string;
41
+ prompt: string;
42
+ model: string;
43
+ size: string;
44
+ ms: number;
45
+ negative?: string;
46
+ } | {
47
+ state: 'none';
48
+ at: string;
49
+ error: string;
50
+ prompt?: string;
51
+ model?: string;
52
+ ms?: number;
53
+ };
54
+ /** 某一轮某张画图卡的记录;过了 PAINT_STALE_MS 还在画的当没画成(stale) */
55
+ export declare function paintRecordAt(ws: PaintSpace, tutor: string, date: string, job: string, n: number, now?: number): Promise<PaintRecord | null>;
56
+ /** 今天各位老师画好的张数(在画的也算);工作台概览用 */
57
+ export declare function paintedToday(ws: PaintSpace, date: string, now?: number): Promise<number>;
58
+ /**
59
+ * 这一轮板书里的画图卡,一张一张画。已经有记录的不再画(重起、重放都不重画);replay = 回放那轮不画(evals 目录里,不花钱)。
60
+ * painter = 这个话题的 activity 文件「画家收到什么」(模板与不要的);给了就照它画,没给照出厂的画风。
61
+ * 返回画完的 Promise(测试与关服前等它),不抛。
62
+ */
63
+ export declare function startPaints(ws: PaintSpace, tutor: string, date: string, job: string, section: BoardSection, opts: {
64
+ draw: Draw;
65
+ now?: () => Date;
66
+ replay?: boolean;
67
+ gate?: () => Promise<string | null>;
68
+ painter?: {
69
+ prompt: string;
70
+ negative?: string;
71
+ } | null;
72
+ }): Promise<void>;
73
+ /** 家长端那一行:画好了用的模型与秒数;没画成的原因说成人话 */
74
+ export declare function paintNote(r: PaintRecord | null): string;
75
+ /**
76
+ * 下发时补上画好没有(同 enrichLectures):pic = 图(相对 workspace 根,页面经 /api/kid/image 取),drawn = drawing / done / none;
77
+ * 家长端(parent)再补 note。没有记录:这一轮刚跑完、还没轮到 → drawing;过了 PAINT_STALE_MS 还没有 → none。
78
+ */
79
+ export declare function enrichPaints(ws: PaintSpace, tutor: string, date: string, job: string, at: string, section: BoardSection, opts?: {
80
+ parent?: boolean;
81
+ now?: number;
82
+ }): Promise<BoardSection>;
83
+ /** 交给老师的那一行(下一条消息的 cards:):老师看不到图,只知道画好没有 */
84
+ export declare function paintLines(ws: PaintSpace, tutor: string, date: string, job: string, section: BoardSection, now?: number): Promise<string[]>;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * 画图卡的画:一轮跑完,板书里的 paint 卡在后台画,和配音同一个时机。
3
+ * 落在这张卡的资产目录 <日期>.<job>.cards/<n>/:paint.png 是图,paint.json 是记录(在画 / 画好了 / 没画成,拼好的提示词、模型、几秒、原因)。
4
+ * 一天画几张不限;今天画了几张由工作台概览数(paintedToday)。
5
+ * 一张一张排着画。孩子端没有错误:没画成就停在分幅那几句,原因只给家长看。
6
+ */
7
+ import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';
8
+ import { join, relative } from 'node:path';
9
+ import { cardId, conversationFiles } from "../../schema/index.js";
10
+ import { PaintPropsSchema } from "../../board/cards/index.js";
11
+ import { PAINT_DEFAULT, PAINT_NEGATIVE } from "../../schema/index.js";
12
+ import { paintPrompt, paintPromptFrom, paintSize } from "./prompt.js";
13
+ export const PAINT_PNG = 'paint.png';
14
+ export const PAINT_JSON = 'paint.json';
15
+ /** 「在画」超过这么久还没落成(服务重起过、进程被杀),当没画成 */
16
+ export const PAINT_STALE_MS = 5 * 60_000;
17
+ /** 某一轮某张画图卡的记录;过了 PAINT_STALE_MS 还在画的当没画成(stale) */
18
+ export async function paintRecordAt(ws, tutor, date, job, n, now = Date.now()) {
19
+ const r = await readRecord(join(conversationFiles(ws.dirs.conversations, tutor, date).cardAssetsDir(job, n), PAINT_JSON));
20
+ return r?.state === 'drawing' && now - Date.parse(r.at) > PAINT_STALE_MS ? { state: 'none', at: r.at, error: 'stale' } : r;
21
+ }
22
+ async function readRecord(file) {
23
+ try {
24
+ const r = JSON.parse(await readFile(file, 'utf8'));
25
+ return r && typeof r.state === 'string' && typeof r.at === 'string' ? r : null;
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ async function writeRecord(file, r) {
32
+ await writeFile(`${file}.tmp`, JSON.stringify(r, null, 2) + '\n');
33
+ await rename(`${file}.tmp`, file);
34
+ }
35
+ /** 今天各位老师画好的张数(在画的也算);工作台概览用 */
36
+ export async function paintedToday(ws, date, now = Date.now()) {
37
+ let n = 0;
38
+ const tutors = await readdir(ws.dirs.conversations, { withFileTypes: true }).catch(() => []);
39
+ for (const t of tutors) {
40
+ if (!t.isDirectory())
41
+ continue;
42
+ const dir = join(ws.dirs.conversations, t.name);
43
+ const names = await readdir(dir).catch(() => []);
44
+ for (const name of names) {
45
+ if (!name.startsWith(`${date}.`) || !name.endsWith('.cards'))
46
+ continue;
47
+ const cards = await readdir(join(dir, name), { withFileTypes: true }).catch(() => []);
48
+ for (const c of cards) {
49
+ if (!c.isDirectory())
50
+ continue;
51
+ const r = await readRecord(join(dir, name, c.name, PAINT_JSON));
52
+ if (r?.state === 'done' || (r?.state === 'drawing' && now - Date.parse(r.at) < PAINT_STALE_MS))
53
+ n++;
54
+ }
55
+ }
56
+ }
57
+ return n;
58
+ }
59
+ /** 一张一张画:整个进程一条队 */
60
+ let chain = Promise.resolve();
61
+ /**
62
+ * 这一轮板书里的画图卡,一张一张画。已经有记录的不再画(重起、重放都不重画);replay = 回放那轮不画(evals 目录里,不花钱)。
63
+ * painter = 这个话题的 activity 文件「画家收到什么」(模板与不要的);给了就照它画,没给照出厂的画风。
64
+ * 返回画完的 Promise(测试与关服前等它),不抛。
65
+ */
66
+ export function startPaints(ws, tutor, date, job, section, opts) {
67
+ const cfg = ws.config.paint ?? PAINT_DEFAULT;
68
+ const painter = opts.painter ?? null;
69
+ const negative = painter?.negative || PAINT_NEGATIVE;
70
+ const files = conversationFiles(ws.dirs.conversations, tutor, date);
71
+ const at = () => (opts.now?.() ?? new Date()).toISOString();
72
+ const work = section.cards.flatMap((c, n) => {
73
+ if (c.kind !== 'paint')
74
+ return [];
75
+ const p = PaintPropsSchema.safeParse(c.props);
76
+ return p.success ? [{ n, props: p.data }] : [];
77
+ });
78
+ if (!work.length)
79
+ return Promise.resolve();
80
+ const run = async () => {
81
+ for (const { n, props } of work) {
82
+ const dir = files.cardAssetsDir(job, n);
83
+ const rec = join(dir, PAINT_JSON);
84
+ if (await readRecord(rec))
85
+ continue;
86
+ await mkdir(dir, { recursive: true });
87
+ const prompt = painter ? paintPromptFrom(painter.prompt, props) : paintPrompt(props);
88
+ const model = cfg.model;
89
+ if (opts.replay) {
90
+ await writeRecord(rec, { state: 'none', at: at(), error: 'replay' });
91
+ continue;
92
+ }
93
+ // activity「应用拦的」:没过就不画、不占张数,下一条告诉老师缺哪条;排在队里现查,同一轮第二张看得到第一张
94
+ const stop = opts.gate ? await opts.gate().catch(() => null) : null;
95
+ if (stop) {
96
+ await writeRecord(rec, { state: 'none', at: at(), error: `gate:${stop}`, prompt, model });
97
+ continue;
98
+ }
99
+ await writeRecord(rec, { state: 'drawing', at: at(), prompt, model, negative });
100
+ const size = paintSize(props.panels.length, cfg.size);
101
+ const r = await opts.draw({ prompt, model, size, negative });
102
+ if (r.ok) {
103
+ await writeFile(join(dir, PAINT_PNG), r.data);
104
+ await writeRecord(rec, { state: 'done', at: at(), prompt, model, size, ms: r.ms, negative });
105
+ }
106
+ else
107
+ await writeRecord(rec, { state: 'none', at: at(), error: r.error, prompt, model, ms: r.ms });
108
+ }
109
+ };
110
+ const p = chain.then(run, run).catch(() => { });
111
+ chain = p;
112
+ return p;
113
+ }
114
+ /** 家长端那一行:画好了用的模型与秒数;没画成的原因说成人话 */
115
+ export function paintNote(r) {
116
+ if (!r)
117
+ return '还没开始画';
118
+ if (r.state === 'drawing')
119
+ return `在画(${r.model})`;
120
+ if (r.state === 'done')
121
+ return `画好了:${r.model},${Math.round(r.ms / 1000)} 秒`;
122
+ const e = r.error;
123
+ // daily: 是 10-21 前一天几张的上限(去掉了),旧记录照旧说得出来
124
+ const why = e.startsWith('daily:') ? `今天画了 ${e.slice(6).split('/')[0]} 张,到了当时一天的上限(现在不限了)`
125
+ : e.startsWith('gate:') ? `应用拦下了,没交给画家(activity「应用拦的」:${e.slice(5)})`
126
+ : e === 'replay' ? '回放不画'
127
+ : e === 'no_key' ? '拿不到百炼 key(DASHSCOPE_API_KEY,或本机 ~/.qwen/settings.json)'
128
+ : e === 'stale' ? '画到一半服务重起了'
129
+ : e.includes('DataInspectionFailed') ? '百炼的内容审核没过'
130
+ : e === 'timeout' ? '等了太久(超时)'
131
+ : e;
132
+ return `没画成:${why}`;
133
+ }
134
+ /**
135
+ * 下发时补上画好没有(同 enrichLectures):pic = 图(相对 workspace 根,页面经 /api/kid/image 取),drawn = drawing / done / none;
136
+ * 家长端(parent)再补 note。没有记录:这一轮刚跑完、还没轮到 → drawing;过了 PAINT_STALE_MS 还没有 → none。
137
+ */
138
+ export async function enrichPaints(ws, tutor, date, job, at, section, opts = {}) {
139
+ if (!section.cards.some((c) => c.kind === 'paint'))
140
+ return section;
141
+ const files = conversationFiles(ws.dirs.conversations, tutor, date);
142
+ const now = opts.now ?? Date.now();
143
+ const cards = await Promise.all(section.cards.map(async (c, n) => {
144
+ if (c.kind !== 'paint')
145
+ return c;
146
+ let r = await readRecord(join(files.cardAssetsDir(job, n), PAINT_JSON));
147
+ const since = (x) => now - Date.parse(x);
148
+ if (r?.state === 'drawing' && since(r.at) > PAINT_STALE_MS)
149
+ r = { state: 'none', at: r.at, error: 'stale' };
150
+ const drawn = r ? (r.state === 'done' ? 'done' : r.state) : since(at) > PAINT_STALE_MS ? 'none' : 'drawing';
151
+ const pic = drawn === 'done' ? relative(ws.root, files.cardAsset(job, n, PAINT_PNG)) : undefined;
152
+ return { ...c, props: { ...c.props, drawn, ...(pic ? { pic } : {}), ...(opts.parent ? { note: paintNote(r) } : {}) } };
153
+ }));
154
+ return { ...section, cards };
155
+ }
156
+ /** 交给老师的那一行(下一条消息的 cards:):老师看不到图,只知道画好没有 */
157
+ export async function paintLines(ws, tutor, date, job, section, now = Date.now()) {
158
+ const files = conversationFiles(ws.dirs.conversations, tutor, date);
159
+ const out = [];
160
+ for (const [n, c] of section.cards.entries()) {
161
+ if (c.kind !== 'paint')
162
+ continue;
163
+ let r = await readRecord(join(files.cardAssetsDir(job, n), PAINT_JSON));
164
+ if (r?.state === 'drawing' && now - Date.parse(r.at) > PAINT_STALE_MS)
165
+ r = { state: 'none', at: r.at, error: 'stale' };
166
+ const said = !r || r.state === 'drawing' ? '画家还在画,孩子还没看到图' : r.state === 'done' ? '画好了,孩子看到了图(你看不到图,问孩子画得怎样)' : r.error === 'gate:连说过一遍' ? '没画:孩子还没看着整段连着说一遍,孩子只看到分好的几幅' : r.error === 'gate:还能画' ? '没画:这个话题能画的张数到头了,孩子只看到分好的几幅' : r.error.startsWith('gate:') ? `没画:${r.error.slice(5)}没过,孩子只看到分好的几幅` : '没画成,孩子只看到分好的几幅';
167
+ out.push(`${cardId(job, n)} 画图卡:${said}`);
168
+ }
169
+ return out;
170
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 画图卡 → 交给文生图模型的一段:版式(几格怎么排)+ 画风 + 角色 + 分幅。
3
+ * 画风在 activity 文件「画家收到什么」那节(模板里留 {{版式}} {{角色}} {{分幅}} 三个插槽);
4
+ * 不在 activity 话题里画,照出厂的画风(PAINT_PROMPT_DEFAULT)夹在版式与角色中间。
5
+ * 纯函数;版式与角色、分幅由这里接,改画风不会把分幅弄丢。
6
+ */
7
+ import type { PaintProps } from '../../board/cards/index.ts';
8
+ /** 反向提示词(百炼限 500 字符);出厂那串在 schema,和画风放一起 */
9
+ export { PAINT_NEGATIVE } from '../../schema/index.ts';
10
+ /** 几格怎么排:四格 2×2(练习册的样子),两三格横排,一幅就是一张画(不提编号:提了模型就往一幅的图上点圆圈数字) */
11
+ export declare function paintLayout(n: number): string;
12
+ /** 画多大:四格与一幅照配置(方的);两三格横排,换成宽的 */
13
+ export declare function paintSize(n: number, size: string): string;
14
+ /** 画家那节的三个插槽:版式、角色(没有就空)、分幅 */
15
+ export declare function paintSlots(p: Pick<PaintProps, 'panels' | 'cast'>): {
16
+ 版式: string;
17
+ 角色: string;
18
+ 分幅: string;
19
+ };
20
+ /** 不在 activity 话题里:版式、出厂的画风、角色、分幅,空一行隔开 */
21
+ export declare function paintPrompt(p: Pick<PaintProps, 'panels' | 'cast'>): string;
22
+ /** activity 文件「画家收到什么」的模板填好插槽 */
23
+ export declare function paintPromptFrom(template: string, p: Pick<PaintProps, 'panels' | 'cast'>): string;
@@ -0,0 +1,36 @@
1
+ import { fillSlots } from "../../schema/index.js";
2
+ import { PAINT_PROMPT_DEFAULT } from "../../schema/index.js";
3
+ /** 反向提示词(百炼限 500 字符);出厂那串在 schema,和画风放一起 */
4
+ export { PAINT_NEGATIVE } from "../../schema/index.js";
5
+ const FRAME = '格子之间留白边,每格有细圆角边框。除了这几个圆圈数字,画面里没有别的字。';
6
+ const NUMS = ['1', '2', '3', '4'];
7
+ /** 几格怎么排:四格 2×2(练习册的样子),两三格横排,一幅就是一张画(不提编号:提了模型就往一幅的图上点圆圈数字) */
8
+ export function paintLayout(n) {
9
+ if (n >= 4)
10
+ return `一张四格连环画,四格按 2×2 排,从左上到右下依次是第 1、2、3、4 格,每格左上角一个圆圈数字。${FRAME}`;
11
+ if (n > 1)
12
+ return `一张${n === 3 ? '三' : '两'}格连环画,${n === 3 ? '三' : '两'}格从左到右横着排,依次是第 ${NUMS.slice(0, n).join('、')} 格,每格左上角一个圆圈数字。${FRAME}`;
13
+ return '一张画。';
14
+ }
15
+ /** 画多大:四格与一幅照配置(方的);两三格横排,换成宽的 */
16
+ export function paintSize(n, size) {
17
+ return n === 2 || n === 3 ? '1664*928' : size;
18
+ }
19
+ /** 画家那节的三个插槽:版式、角色(没有就空)、分幅 */
20
+ export function paintSlots(p) {
21
+ const n = p.panels.length;
22
+ return {
23
+ 版式: paintLayout(n),
24
+ 角色: p.cast?.length ? [`同一个角色在${n > 1 ? '每一格里' : '画里'}长相、颜色、衣服都照这样画:`, ...p.cast.map((c) => (c.look ? `- ${c.name}:${c.look}` : `- ${c.name}`))].join('\n') : '',
25
+ 分幅: n > 1 ? p.panels.map((t, i) => `第 ${i + 1} 格:${t}`).join('\n') : `画面:${p.panels[0]}`,
26
+ };
27
+ }
28
+ /** 不在 activity 话题里:版式、出厂的画风、角色、分幅,空一行隔开 */
29
+ export function paintPrompt(p) {
30
+ const s = paintSlots(p);
31
+ return [s.版式, PAINT_PROMPT_DEFAULT.join('\n'), s.角色, s.分幅].filter(Boolean).join('\n\n');
32
+ }
33
+ /** activity 文件「画家收到什么」的模板填好插槽 */
34
+ export function paintPromptFrom(template, p) {
35
+ return fillSlots(template, paintSlots(p));
36
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 孩子说的英文说出了几个词:实时老师的热身(src/scenes/talk/warmup.ts)用。纯函数。
3
+ * 比的是转写的字,不是发音:百炼的转写会往对的词上靠(coach),说出来了不等于念对了。
4
+ */
5
+ /** 小写、展开常见缩写、去标点,拆成词 */
6
+ export declare function wordsOf(s: string): string[];
7
+ /** 这句(target)的词有多少出现在孩子读的(heard)里,0–1;不分先后 */
8
+ export declare function coverage(target: string, heard: string): number;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * 孩子说的英文说出了几个词:实时老师的热身(src/scenes/talk/warmup.ts)用。纯函数。
3
+ * 比的是转写的字,不是发音:百炼的转写会往对的词上靠(coach),说出来了不等于念对了。
4
+ */
5
+ const CONTRACT = { "it's": 'it is', "i'm": 'i am', "that's": 'that is', "what's": 'what is', "he's": 'he is', "she's": 'she is', "there's": 'there is', "don't": 'do not', "can't": 'can not', "isn't": 'is not', "you're": 'you are', "they're": 'they are', "we're": 'we are', "let's": 'let us', "i'll": 'i will' };
6
+ /** 小写、展开常见缩写、去标点,拆成词 */
7
+ export function wordsOf(s) {
8
+ const t = s.toLowerCase().replace(/[’`]/g, "'").replace(/[^a-z' ]+/g, ' ');
9
+ return t.split(/\s+/).flatMap((w) => (CONTRACT[w] ?? w.replace(/^'+|'+$/g, '')).split(' ')).filter(Boolean);
10
+ }
11
+ /** 两个词算不算同一个:一样;或四个字母以上差一个字母(认字的错一个字母常见:colour / color、apples / apple) */
12
+ function near(a, b) {
13
+ if (a === b)
14
+ return true;
15
+ if (Math.min(a.length, b.length) < 4 || Math.abs(a.length - b.length) > 1)
16
+ return false;
17
+ let i = 0, j = 0, diff = 0;
18
+ while (i < a.length && j < b.length) {
19
+ if (a[i] === b[j]) {
20
+ i++;
21
+ j++;
22
+ continue;
23
+ }
24
+ if (++diff > 1)
25
+ return false;
26
+ if (a.length > b.length)
27
+ i++;
28
+ else if (b.length > a.length)
29
+ j++;
30
+ else {
31
+ i++;
32
+ j++;
33
+ }
34
+ }
35
+ return diff + (a.length - i) + (b.length - j) <= 1;
36
+ }
37
+ /** 这句(target)的词有多少出现在孩子读的(heard)里,0–1;不分先后 */
38
+ export function coverage(target, heard) {
39
+ const want = [...new Set(wordsOf(target))];
40
+ if (!want.length)
41
+ return 0;
42
+ const got = wordsOf(heard);
43
+ return want.filter((w) => got.some((g) => near(w, g))).length / want.length;
44
+ }
@@ -0,0 +1,44 @@
1
+ import type { Look } from '../look.ts';
2
+ /** 口语单的一条;词另有单词卡(cards/word)要的 emoji 与自然拼读分段(读照片时出,过 cards/word 的 parse;没有就卡上只有词) */
3
+ export interface ListItem {
4
+ en: string;
5
+ zh: string;
6
+ emoji?: string;
7
+ chunks?: string[];
8
+ }
9
+ export interface TalkList {
10
+ words: ListItem[];
11
+ sentences: ListItem[];
12
+ }
13
+ export declare const LIST_TIMEOUT_MS = 40000;
14
+ export declare const PROMPT = "\u8FD9\u662F\u5BB6\u957F\u62CD\u7684\u4E00\u9875\u5C0F\u5B66\u82F1\u8BED\u8BFE\u672C\u6216\u7EC3\u4E60\u518C\u3002\u628A\u8FD9\u4E00\u9875\u4E0A**\u5370\u5237\u7684**\u82F1\u6587\u5355\u8BCD\u548C\u82F1\u6587\u53E5\u5B50\u8BFB\u51FA\u6765,\u7ED9\u5B69\u5B50\u8DDF\u8BFB\u548C\u53E3\u8BED\u7EC3\u4E60\u7528:\n- words:\u5355\u8BCD\u6216\u77ED\u8BED(\u6700\u591A 12 \u4E2A),\u6BCF\u4E2A\u5E26\u4E2D\u6587\u610F\u601D;\u518D\u5E26\u4E24\u6837\u7ED9\u5355\u8BCD\u5361\u7528:emoji\u2014\u2014\u80FD\u753B\u51FA\u6765\u7684\u4E1C\u897F\u914D\u4E00\u4E2A,\u62BD\u8C61\u7684\u8BCD(like\u3001the)\u4E0D\u914D;split\u2014\u2014\u81EA\u7136\u62FC\u8BFB\u5206\u6BB5,\u7528 - \u9694\u5F00(ap-ple\u3001sh-ee-p\u3001c-a-t),\u62FC\u8D77\u6765\u8981\u548C\u5355\u8BCD\u4E00\u6A21\u4E00\u6837;\n- sentences:\u5B8C\u6574\u7684\u82F1\u6587\u53E5\u5B50(\u6700\u591A 8 \u53E5),\u6BCF\u53E5\u5E26\u4E2D\u6587\u610F\u601D;\n- \u53EA\u8981\u5370\u5237\u7684,\u624B\u5199\u7684\u4E0D\u8981;\u9898\u53F7\u3001\u9875\u7801\u3001\u680F\u76EE\u540D\u4E0D\u8981;\u62FC\u97F3\u3001\u97F3\u6807\u4E0D\u8981;\n- \u8FD9\u4E00\u9875\u6CA1\u6709\u82F1\u6587\u5C31\u4E24\u4E2A\u90FD\u7A7A\u3002\n\u53EA\u56DE\u4E00\u4E2A JSON \u5BF9\u8C61,\u5F62\u5982 {\"words\":[{\"en\":\"red\",\"zh\":\"\u7EA2\u8272\",\"emoji\":\"\uD83D\uDD34\",\"split\":\"r-e-d\"}],\"sentences\":[{\"en\":\"It's a red car.\",\"zh\":\"\u8FD9\u662F\u4E00\u8F86\u7EA2\u8272\u7684\u8F66\u3002\"}]},\u4E0D\u8981\u522B\u7684\u5B57\u3002";
15
+ /**
16
+ * 口语单的一个词 → 单词卡要的 emoji 与分段:拼成单词卡的正文过 cards/word 的 parse,
17
+ * 分段拼不回这个词就丢分段、emoji 不是 emoji 就丢——和老师写错时一个下场;词本身写不进四线三格(带标点、整句)两样都不要
18
+ */
19
+ export declare function wordCardOf(en: string, emoji?: unknown, split?: unknown): {
20
+ emoji?: string;
21
+ chunks?: string[];
22
+ };
23
+ export type ListResult = {
24
+ ok: true;
25
+ list: TalkList;
26
+ model: string;
27
+ ms: number;
28
+ } | {
29
+ ok: false;
30
+ error: string;
31
+ ms: number;
32
+ };
33
+ /** 模型回的字 → 口语单;去掉围栏、找到第一个 {…};形状不对回 null */
34
+ export declare function parseList(text: string): TalkList | null;
35
+ /** 读一张照片(look = 看图的请求,src/media/vision.ts 的 lookAt);不抛,出错回 {ok: false} */
36
+ export declare function readListWith(look: Look, photo: {
37
+ data: Buffer;
38
+ mime: string;
39
+ }, opts?: {
40
+ env?: NodeJS.ProcessEnv;
41
+ endpoint?: string;
42
+ model?: string;
43
+ timeoutMs?: number;
44
+ }): Promise<ListResult>;