cotutor 0.2.0 → 0.4.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 (912) hide show
  1. package/LICENSE +249 -21
  2. package/NOTICE +42 -0
  3. package/README.md +115 -20
  4. package/avatars/chinese.webp +0 -0
  5. package/avatars/english.webp +0 -0
  6. package/avatars/math.webp +0 -0
  7. package/bin/cotutor.js +15 -5
  8. package/cards/canvas/card.css +8 -0
  9. package/cards/canvas/card.md +68 -0
  10. package/cards/choice/card.css +18 -0
  11. package/cards/choice/card.md +55 -0
  12. package/cards/code/card.css +5 -0
  13. package/cards/code/card.md +46 -0
  14. package/cards/dictation/card.css +10 -0
  15. package/cards/dictation/card.md +97 -0
  16. package/cards/image/card.css +10 -0
  17. package/cards/image/card.md +52 -0
  18. package/cards/lecture/card.css +9 -0
  19. package/cards/lecture/card.md +69 -0
  20. package/cards/paint/card.css +20 -0
  21. package/cards/paint/card.md +77 -0
  22. package/cards/photo/card.css +22 -0
  23. package/cards/photo/card.md +61 -0
  24. package/cards/read/card.css +6 -0
  25. package/cards/read/card.md +51 -0
  26. package/cards/text/card.css +3 -0
  27. package/cards/text/card.md +69 -0
  28. package/cards/tianzige/card.css +17 -0
  29. package/cards/tianzige/card.md +78 -0
  30. package/cards/tutor/card.css +79 -0
  31. package/cards/tutor/card.md +149 -0
  32. package/cards/word/card.css +24 -0
  33. package/cards/word/card.md +91 -0
  34. package/cards//346/235/277/344/271/246/346/200/216/344/271/210/345/206/231.md +159 -0
  35. package/dist/app/activity-eval-rules.d.ts +62 -0
  36. package/dist/app/activity-eval-rules.js +276 -0
  37. package/dist/app/activity-eval.d.ts +65 -0
  38. package/dist/app/activity-eval.js +159 -0
  39. package/dist/app/build.d.ts +11 -0
  40. package/dist/app/build.js +45 -0
  41. package/dist/app/cli/activities.d.ts +70 -0
  42. package/dist/app/cli/activities.js +196 -0
  43. package/dist/app/cli/cert.d.ts +12 -0
  44. package/dist/app/cli/cert.js +49 -0
  45. package/dist/app/cli/chalk/bake.d.ts +10 -0
  46. package/dist/app/cli/chalk/bake.js +58 -0
  47. package/dist/app/cli/chalk/browser.d.ts +16 -0
  48. package/dist/app/cli/chalk/browser.js +157 -0
  49. package/dist/app/cli/chalk/build.d.ts +14 -0
  50. package/dist/app/cli/chalk/build.js +100 -0
  51. package/dist/app/cli/chalk/dub.d.ts +51 -0
  52. package/dist/app/cli/chalk/dub.js +106 -0
  53. package/dist/app/cli/chalk/load-scene.d.ts +34 -0
  54. package/dist/app/cli/chalk/load-scene.js +117 -0
  55. package/dist/app/cli/chalk/main.d.ts +7 -0
  56. package/dist/app/cli/chalk/main.js +199 -0
  57. package/dist/app/cli/chalk/serve.d.ts +4 -0
  58. package/dist/app/cli/chalk/serve.js +28 -0
  59. package/dist/app/cli/chalk/snap.d.ts +65 -0
  60. package/dist/app/cli/chalk/snap.js +103 -0
  61. package/dist/app/cli/chalk/typecheck.d.ts +7 -0
  62. package/dist/app/cli/chalk/typecheck.js +51 -0
  63. package/dist/app/cli/doctor.d.ts +24 -0
  64. package/dist/app/cli/doctor.js +553 -0
  65. package/dist/app/cli/firewall.d.ts +24 -0
  66. package/dist/app/cli/firewall.js +79 -0
  67. package/dist/app/cli/grades.d.ts +14 -0
  68. package/dist/app/cli/grades.js +44 -0
  69. package/dist/{cli → app/cli}/init.d.ts +3 -1
  70. package/dist/app/cli/init.js +158 -0
  71. package/dist/app/cli/main.js +1038 -0
  72. package/dist/app/cli/migrate.d.ts +49 -0
  73. package/dist/app/cli/migrate.js +195 -0
  74. package/dist/app/cli/port-holder.d.ts +16 -0
  75. package/dist/app/cli/port-holder.js +34 -0
  76. package/dist/app/cli/port.d.ts +37 -0
  77. package/dist/app/cli/port.js +116 -0
  78. package/dist/app/cli/sandbox.d.ts +25 -0
  79. package/dist/app/cli/sandbox.js +166 -0
  80. package/dist/app/cli/serve-log.d.ts +13 -0
  81. package/dist/app/cli/serve-log.js +90 -0
  82. package/dist/app/cli/serve.d.ts +51 -0
  83. package/dist/app/cli/serve.js +168 -0
  84. package/dist/app/cli/service-windows.d.ts +50 -0
  85. package/dist/app/cli/service-windows.js +117 -0
  86. package/dist/app/cli/service.d.ts +138 -0
  87. package/dist/app/cli/service.js +429 -0
  88. package/dist/app/cli/shipped.d.ts +30 -0
  89. package/dist/app/cli/shipped.js +47 -0
  90. package/dist/app/cli/skeleton.d.ts +38 -0
  91. package/dist/app/cli/skeleton.js +161 -0
  92. package/dist/app/cli/skills.d.ts +59 -0
  93. package/dist/app/cli/skills.js +199 -0
  94. package/dist/app/cli/themes.d.ts +52 -0
  95. package/dist/app/cli/themes.js +148 -0
  96. package/dist/app/cli/tray-icons.d.ts +11 -0
  97. package/dist/app/cli/tray-icons.js +87 -0
  98. package/dist/app/cli/tray-ids.d.ts +6 -0
  99. package/dist/app/cli/tray-ids.js +6 -0
  100. package/dist/app/cli/tray-mac.d.ts +8 -0
  101. package/dist/app/cli/tray-mac.js +140 -0
  102. package/dist/app/cli/tray-run.d.ts +1 -0
  103. package/dist/app/cli/tray-run.js +33 -0
  104. package/dist/app/cli/tray-windows.d.ts +5 -0
  105. package/dist/app/cli/tray-windows.js +166 -0
  106. package/dist/app/cli/tray.d.ts +205 -0
  107. package/dist/app/cli/tray.js +618 -0
  108. package/dist/{cli → app/cli}/tutors.d.ts +15 -26
  109. package/dist/{cli → app/cli}/tutors.js +86 -110
  110. package/dist/app/cli/usage.d.ts +2 -0
  111. package/dist/app/cli/usage.js +35 -0
  112. package/dist/app/dictation/recognize.d.ts +18 -0
  113. package/dist/app/dictation/recognize.js +6 -0
  114. package/dist/app/dictation/route.d.ts +52 -0
  115. package/dist/app/dictation/route.js +511 -0
  116. package/dist/app/diff.d.ts +11 -0
  117. package/dist/app/diff.js +71 -0
  118. package/dist/app/http/access.d.ts +62 -0
  119. package/dist/app/http/access.js +180 -0
  120. package/dist/app/http/app.d.ts +241 -0
  121. package/dist/app/http/app.js +1159 -0
  122. package/dist/app/http/avatars.d.ts +17 -0
  123. package/dist/app/http/avatars.js +35 -0
  124. package/dist/app/http/dev-activities.d.ts +115 -0
  125. package/dist/app/http/dev-activities.js +193 -0
  126. package/dist/app/http/dev-overview.d.ts +108 -0
  127. package/dist/app/http/dev-overview.js +209 -0
  128. package/dist/app/http/dev-tutor-files.d.ts +80 -0
  129. package/dist/app/http/dev-tutor-files.js +151 -0
  130. package/dist/app/http/parent-home.d.ts +51 -0
  131. package/dist/app/http/parent-home.js +266 -0
  132. package/dist/app/http/parent-look.d.ts +2 -0
  133. package/dist/app/http/parent-look.js +151 -0
  134. package/dist/app/http/range.d.ts +9 -0
  135. package/dist/app/http/range.js +19 -0
  136. package/dist/app/http/raw-view.d.ts +117 -0
  137. package/dist/app/http/raw-view.js +149 -0
  138. package/dist/app/http/send-file.d.ts +7 -0
  139. package/dist/app/http/send-file.js +29 -0
  140. package/dist/{server → app/http}/stage.d.ts +9 -0
  141. package/dist/{server → app/http}/stage.js +34 -6
  142. package/dist/app/http/theme.d.ts +13 -0
  143. package/dist/app/http/theme.js +41 -0
  144. package/dist/app/http/voice-preview.d.ts +4 -0
  145. package/dist/app/http/voice-preview.js +34 -0
  146. package/dist/app/machine/bailian.d.ts +26 -0
  147. package/dist/app/machine/bailian.js +87 -0
  148. package/dist/app/mock/mock-live.d.ts +16 -0
  149. package/dist/app/mock/mock-live.js +140 -0
  150. package/dist/{server → app/mock}/mock.d.ts +38 -5
  151. package/dist/app/mock/mock.js +1125 -0
  152. package/dist/app/replay.d.ts +94 -0
  153. package/dist/app/replay.js +170 -0
  154. package/dist/app/skills/analyze-doc.d.ts +3 -0
  155. package/dist/app/skills/analyze-doc.js +47 -0
  156. package/dist/app/skills/home-doc.d.ts +5 -0
  157. package/dist/app/skills/home-doc.js +112 -0
  158. package/dist/app/skills/tune-doc.d.ts +3 -0
  159. package/dist/app/skills/tune-doc.js +80 -0
  160. package/dist/app/talk/list.d.ts +11 -0
  161. package/dist/app/talk/list.js +9 -0
  162. package/dist/app/talk/route.d.ts +16 -0
  163. package/dist/app/talk/route.js +142 -0
  164. package/dist/app/workspace.d.ts +63 -0
  165. package/dist/{cli → app}/workspace.js +100 -52
  166. package/dist/app/ws/route.d.ts +31 -0
  167. package/dist/app/ws/route.js +33 -0
  168. package/dist/app/ws/ws.d.ts +31 -0
  169. package/dist/app/ws/ws.js +169 -0
  170. package/dist/board/canvas-chat.d.ts +97 -0
  171. package/dist/board/canvas-chat.js +175 -0
  172. package/dist/board/card-guards.d.ts +15 -0
  173. package/dist/board/card-guards.js +38 -0
  174. package/dist/board/cards/canvas.d.ts +41 -0
  175. package/dist/board/cards/canvas.js +83 -0
  176. package/dist/{cards → board/cards}/choice.js +0 -12
  177. package/dist/{cards → board/cards}/code.js +0 -3
  178. package/dist/board/cards/dictation.d.ts +42 -0
  179. package/dist/board/cards/dictation.js +105 -0
  180. package/dist/board/cards/docs.d.ts +47 -0
  181. package/dist/board/cards/docs.js +152 -0
  182. package/dist/{cards → board/cards}/image.js +1 -10
  183. package/dist/board/cards/index.d.ts +62 -0
  184. package/dist/board/cards/index.js +144 -0
  185. package/dist/{cards → board/cards}/kind.d.ts +10 -4
  186. package/dist/board/cards/kind.js +9 -0
  187. package/dist/board/cards/lecture.d.ts +26 -0
  188. package/dist/board/cards/lecture.js +62 -0
  189. package/dist/board/cards/paint.d.ts +38 -0
  190. package/dist/board/cards/paint.js +85 -0
  191. package/dist/board/cards/photo.d.ts +15 -0
  192. package/dist/board/cards/photo.js +29 -0
  193. package/dist/{cards → board/cards}/read.js +1 -10
  194. package/dist/board/cards/text.d.ts +20 -0
  195. package/dist/board/cards/text.js +59 -0
  196. package/dist/board/cards/tianzige.d.ts +16 -0
  197. package/dist/board/cards/tianzige.js +64 -0
  198. package/dist/board/cards/tutor.d.ts +72 -0
  199. package/dist/board/cards/tutor.js +134 -0
  200. package/dist/board/cards/word.d.ts +20 -0
  201. package/dist/board/cards/word.js +76 -0
  202. package/dist/board/lecture.d.ts +100 -0
  203. package/dist/board/lecture.js +204 -0
  204. package/dist/board/paper.d.ts +20 -0
  205. package/dist/board/paper.js +76 -0
  206. package/dist/board/parse.d.ts +118 -0
  207. package/dist/board/parse.js +324 -0
  208. package/dist/board/presentation.d.ts +289 -0
  209. package/dist/board/presentation.js +613 -0
  210. package/dist/board/sections.d.ts +16 -0
  211. package/dist/board/sections.js +130 -0
  212. package/dist/brain/api-tools.d.ts +8 -0
  213. package/dist/brain/api-tools.js +191 -0
  214. package/dist/brain/api.d.ts +57 -0
  215. package/dist/brain/api.js +394 -0
  216. package/dist/brain/index.d.ts +97 -0
  217. package/dist/brain/index.js +11 -0
  218. package/dist/brain/log.d.ts +5 -0
  219. package/dist/brain/log.js +22 -0
  220. package/dist/brain/runtime.d.ts +30 -0
  221. package/dist/brain/runtime.js +23 -0
  222. package/dist/brain/stream-json.d.ts +16 -0
  223. package/dist/brain/stream-json.js +82 -0
  224. package/dist/brain/stream.d.ts +20 -0
  225. package/dist/brain/stream.js +70 -0
  226. package/dist/brain/transcript.d.ts +45 -0
  227. package/dist/brain/transcript.js +132 -0
  228. package/dist/brain/types.d.ts +99 -0
  229. package/dist/brain/types.js +14 -0
  230. package/dist/chalk/actions.d.ts +37 -0
  231. package/dist/chalk/actions.js +69 -0
  232. package/dist/chalk/bundle.d.ts +26 -0
  233. package/dist/chalk/bundle.js +69 -0
  234. package/dist/chalk/check.d.ts +28 -0
  235. package/dist/chalk/check.js +291 -0
  236. package/dist/chalk/circle.d.ts +64 -0
  237. package/dist/chalk/circle.js +193 -0
  238. package/dist/chalk/clock.d.ts +84 -0
  239. package/dist/chalk/clock.js +84 -0
  240. package/dist/chalk/geometry.d.ts +44 -0
  241. package/dist/chalk/geometry.js +139 -0
  242. package/dist/chalk/glyphs/capitals.d.ts +12 -0
  243. package/dist/chalk/glyphs/capitals.js +264 -0
  244. package/dist/chalk/glyphs/index.d.ts +21 -0
  245. package/dist/chalk/glyphs/index.js +18 -0
  246. package/dist/chalk/glyphs/letters.d.ts +13 -0
  247. package/dist/chalk/glyphs/letters.js +280 -0
  248. package/dist/chalk/glyphs/metrics.d.ts +33 -0
  249. package/dist/chalk/glyphs/metrics.js +28 -0
  250. package/dist/chalk/glyphs/registry.d.ts +7 -0
  251. package/dist/chalk/glyphs/registry.js +8 -0
  252. package/dist/chalk/glyphs/sample.d.ts +32 -0
  253. package/dist/chalk/glyphs/sample.js +102 -0
  254. package/dist/chalk/glyphs/skeleton.d.ts +64 -0
  255. package/dist/chalk/glyphs/skeleton.js +126 -0
  256. package/dist/chalk/glyphs/types.d.ts +58 -0
  257. package/dist/chalk/glyphs/types.js +17 -0
  258. package/dist/chalk/index.d.ts +23 -0
  259. package/dist/chalk/index.js +15 -0
  260. package/dist/chalk/manifest.d.ts +41 -0
  261. package/dist/chalk/manifest.js +6 -0
  262. package/dist/chalk/paint.d.ts +180 -0
  263. package/dist/chalk/paint.js +210 -0
  264. package/dist/chalk/pointer.d.ts +8 -0
  265. package/dist/chalk/pointer.js +21 -0
  266. package/dist/chalk/prepare.d.ts +11 -0
  267. package/dist/chalk/prepare.js +15 -0
  268. package/dist/chalk/scene-schema.d.ts +199 -0
  269. package/dist/chalk/scene-schema.js +91 -0
  270. package/dist/chalk/seed.d.ts +3 -0
  271. package/dist/chalk/seed.js +10 -0
  272. package/dist/chalk/text-metrics.d.ts +8 -0
  273. package/dist/chalk/text-metrics.js +156 -0
  274. package/dist/chalk/timeline.d.ts +47 -0
  275. package/dist/chalk/timeline.js +84 -0
  276. package/dist/chalk/types.d.ts +150 -0
  277. package/dist/chalk/types.js +8 -0
  278. package/dist/lib/index.d.ts +14 -12
  279. package/dist/lib/index.js +14 -12
  280. package/dist/media/draw.d.ts +23 -0
  281. package/dist/media/draw.js +44 -0
  282. package/dist/media/mp3.d.ts +6 -0
  283. package/dist/media/mp3.js +58 -0
  284. package/dist/media/mp4.d.ts +1 -0
  285. package/dist/media/mp4.js +58 -0
  286. package/dist/media/tts-voices.d.ts +18 -0
  287. package/dist/media/tts-voices.js +606 -0
  288. package/dist/media/tts.d.ts +56 -0
  289. package/dist/media/tts.js +174 -0
  290. package/dist/media/vision.d.ts +25 -0
  291. package/dist/media/vision.js +71 -0
  292. package/dist/memory/commit.d.ts +67 -0
  293. package/dist/memory/commit.js +130 -0
  294. package/dist/memory/context.d.ts +86 -0
  295. package/dist/memory/context.js +97 -0
  296. package/dist/memory/diary.d.ts +84 -0
  297. package/dist/memory/diary.js +183 -0
  298. package/dist/memory/grade.d.ts +2 -0
  299. package/dist/memory/grade.js +7 -0
  300. package/dist/{lib → memory}/plan.d.ts +1 -1
  301. package/dist/{lib → memory}/plan.js +1 -1
  302. package/dist/memory/proposals.d.ts +11 -0
  303. package/dist/memory/proposals.js +43 -0
  304. package/dist/memory/retrieval.d.ts +44 -0
  305. package/dist/memory/retrieval.js +157 -0
  306. package/dist/{lib → memory}/timetable.d.ts +0 -3
  307. package/dist/{lib → memory}/timetable.js +0 -11
  308. package/dist/memory/vault-notes.d.ts +165 -0
  309. package/dist/memory/vault-notes.js +359 -0
  310. package/dist/memory/vault.d.ts +70 -0
  311. package/dist/memory/vault.js +169 -0
  312. package/dist/realtime/bailian.d.ts +120 -0
  313. package/dist/realtime/bailian.js +289 -0
  314. package/dist/realtime/cues.d.ts +51 -0
  315. package/dist/realtime/cues.js +94 -0
  316. package/dist/realtime/listen.d.ts +32 -0
  317. package/dist/realtime/listen.js +53 -0
  318. package/dist/realtime/preview.d.ts +23 -0
  319. package/dist/realtime/preview.js +38 -0
  320. package/dist/realtime/prompt.d.ts +8 -0
  321. package/dist/realtime/prompt.js +13 -0
  322. package/dist/realtime/voices.d.ts +21 -0
  323. package/dist/realtime/voices.js +71 -0
  324. package/dist/runtime/activities.d.ts +29 -0
  325. package/dist/runtime/activities.js +72 -0
  326. package/dist/runtime/activity-state.d.ts +22 -0
  327. package/dist/runtime/activity-state.js +83 -0
  328. package/dist/runtime/activity.d.ts +63 -0
  329. package/dist/runtime/activity.js +428 -0
  330. package/dist/runtime/agent-file.d.ts +24 -0
  331. package/dist/runtime/agent-file.js +59 -0
  332. package/dist/runtime/auto-bookkeep.d.ts +30 -0
  333. package/dist/runtime/auto-bookkeep.js +84 -0
  334. package/dist/{lib → runtime/context}/context-pack.d.ts +3 -3
  335. package/dist/runtime/context/context-pack.js +182 -0
  336. package/dist/runtime/context/thread-digest.d.ts +4 -0
  337. package/dist/runtime/context/thread-digest.js +35 -0
  338. package/dist/runtime/context/tutor-rules.d.ts +25 -0
  339. package/dist/runtime/context/tutor-rules.js +47 -0
  340. package/dist/runtime/delivery/delivery.d.ts +94 -0
  341. package/dist/runtime/delivery/delivery.js +145 -0
  342. package/dist/runtime/delivery/playback.d.ts +25 -0
  343. package/dist/runtime/delivery/playback.js +29 -0
  344. package/dist/runtime/delivery/player.d.ts +145 -0
  345. package/dist/runtime/delivery/player.js +221 -0
  346. package/dist/runtime/delivery/queue.d.ts +89 -0
  347. package/dist/runtime/delivery/queue.js +59 -0
  348. package/dist/runtime/home/edit.d.ts +39 -0
  349. package/dist/runtime/home/edit.js +132 -0
  350. package/dist/runtime/home/home.d.ts +191 -0
  351. package/dist/runtime/home/home.js +318 -0
  352. package/dist/runtime/home/store.d.ts +142 -0
  353. package/dist/runtime/home/store.js +455 -0
  354. package/dist/runtime/journal/conversation.d.ts +46 -0
  355. package/dist/runtime/journal/conversation.js +89 -0
  356. package/dist/runtime/journal/events.d.ts +27 -0
  357. package/dist/runtime/journal/events.js +136 -0
  358. package/dist/runtime/journal/kid-log.d.ts +105 -0
  359. package/dist/runtime/journal/kid-log.js +133 -0
  360. package/dist/runtime/journal/ledger.d.ts +17 -0
  361. package/dist/{lib → runtime/journal}/ledger.js +7 -40
  362. package/dist/runtime/journal/mix.d.ts +42 -0
  363. package/dist/runtime/journal/mix.js +129 -0
  364. package/dist/runtime/journal/mouth-index.d.ts +26 -0
  365. package/dist/runtime/journal/mouth-index.js +34 -0
  366. package/dist/runtime/journal/mouth.d.ts +54 -0
  367. package/dist/runtime/journal/mouth.js +102 -0
  368. package/dist/runtime/journal/recorder.d.ts +91 -0
  369. package/dist/runtime/journal/recorder.js +148 -0
  370. package/dist/runtime/journal/store.d.ts +123 -0
  371. package/dist/runtime/journal/store.js +316 -0
  372. package/dist/runtime/kid-input.d.ts +16 -0
  373. package/dist/runtime/kid-input.js +194 -0
  374. package/dist/runtime/kid-view.d.ts +124 -0
  375. package/dist/runtime/kid-view.js +157 -0
  376. package/dist/runtime/lecture.d.ts +86 -0
  377. package/dist/runtime/lecture.js +237 -0
  378. package/dist/runtime/live/call.d.ts +231 -0
  379. package/dist/runtime/live/call.js +1244 -0
  380. package/dist/runtime/live/turns.d.ts +48 -0
  381. package/dist/runtime/live/turns.js +102 -0
  382. package/dist/runtime/runner.d.ts +243 -0
  383. package/dist/runtime/runner.js +777 -0
  384. package/dist/runtime/talk-run.d.ts +21 -0
  385. package/dist/runtime/talk-run.js +34 -0
  386. package/dist/scenes/dictation/match.d.ts +57 -0
  387. package/dist/scenes/dictation/match.js +255 -0
  388. package/dist/scenes/dictation/recognize.d.ts +86 -0
  389. package/dist/scenes/dictation/recognize.js +163 -0
  390. package/dist/scenes/dictation/store.d.ts +112 -0
  391. package/dist/scenes/dictation/store.js +99 -0
  392. package/dist/scenes/look.d.ts +26 -0
  393. package/dist/scenes/look.js +1 -0
  394. package/dist/scenes/paint/painter.d.ts +84 -0
  395. package/dist/scenes/paint/painter.js +171 -0
  396. package/dist/scenes/paint/prompt.d.ts +23 -0
  397. package/dist/scenes/paint/prompt.js +36 -0
  398. package/dist/scenes/talk/en-words.d.ts +8 -0
  399. package/dist/scenes/talk/en-words.js +44 -0
  400. package/dist/scenes/talk/list.d.ts +44 -0
  401. package/dist/scenes/talk/list.js +88 -0
  402. package/dist/scenes/talk/store.d.ts +27 -0
  403. package/dist/scenes/talk/store.js +61 -0
  404. package/dist/scenes/talk/warmup.d.ts +16 -0
  405. package/dist/scenes/talk/warmup.js +39 -0
  406. package/dist/schema/activity.d.ts +149 -0
  407. package/dist/schema/activity.js +113 -0
  408. package/dist/schema/board.d.ts +143 -2
  409. package/dist/schema/board.js +15 -3
  410. package/dist/schema/config.d.ts +339 -103
  411. package/dist/schema/config.js +269 -84
  412. package/dist/schema/context-pack.d.ts +76 -14
  413. package/dist/schema/context-pack.js +91 -10
  414. package/dist/{lib/conversation.d.ts → schema/conversation-files.d.ts} +11 -33
  415. package/dist/schema/conversation-files.js +26 -0
  416. package/dist/schema/conversation.d.ts +391 -49
  417. package/dist/schema/conversation.js +135 -19
  418. package/dist/schema/events.d.ts +138 -0
  419. package/dist/schema/events.js +1 -0
  420. package/dist/schema/home.d.ts +56 -0
  421. package/dist/schema/home.js +35 -0
  422. package/dist/schema/index.d.ts +14 -3
  423. package/dist/schema/index.js +14 -3
  424. package/dist/schema/kid-device.d.ts +20 -0
  425. package/dist/schema/kid-device.js +32 -0
  426. package/dist/schema/ledger.d.ts +8 -63
  427. package/dist/schema/ledger.js +7 -31
  428. package/dist/schema/memory.d.ts +73 -0
  429. package/dist/schema/memory.js +47 -0
  430. package/dist/schema/plan.d.ts +2 -2
  431. package/dist/schema/plan.js +2 -2
  432. package/dist/schema/sections.d.ts +32 -25
  433. package/dist/schema/sections.js +21 -22
  434. package/dist/schema/theme.d.ts +25 -0
  435. package/dist/schema/theme.js +26 -0
  436. package/dist/schema/timetable.d.ts +2 -2
  437. package/dist/schema/timetable.js +2 -2
  438. package/dist/schema/workspace.d.ts +68 -0
  439. package/dist/schema/workspace.js +37 -0
  440. package/dist/shared/default-port.d.ts +2 -0
  441. package/dist/shared/default-port.js +2 -0
  442. package/dist/shared/errors.d.ts +8 -0
  443. package/dist/shared/errors.js +13 -0
  444. package/dist/shared/home.d.ts +2 -0
  445. package/dist/shared/home.js +16 -0
  446. package/dist/shared/human-notes.d.ts +5 -0
  447. package/dist/shared/human-notes.js +7 -0
  448. package/dist/shared/qianwen.d.ts +54 -0
  449. package/dist/shared/qianwen.js +113 -0
  450. package/dist/shared/site-url.d.ts +2 -0
  451. package/dist/shared/site-url.js +5 -0
  452. package/dist/shared/time.d.ts +9 -0
  453. package/dist/shared/time.js +22 -0
  454. package/dist/shared/tokens.d.ts +18 -0
  455. package/dist/shared/tokens.js +11 -0
  456. package/dist/shared/wav.d.ts +10 -0
  457. package/dist/shared/wav.js +50 -0
  458. package/dist/stage/chunk-226TNLQA.js +129 -0
  459. package/dist/stage/chunk-24LGQEKE.js +1 -0
  460. package/dist/stage/chunk-25XV6UY3.js +10 -0
  461. package/dist/stage/chunk-2AZI3NHJ.js +1 -0
  462. package/dist/stage/chunk-2BQZTTBE.js +1 -0
  463. package/dist/stage/chunk-2M7CGY3Y.js +11 -0
  464. package/dist/stage/chunk-2VR4WFQ7.js +10 -0
  465. package/dist/stage/chunk-2ZYXBUWG.js +9 -0
  466. package/dist/stage/chunk-32LAWMGY.js +1 -0
  467. package/dist/stage/chunk-3LEMTSOO.js +11 -0
  468. package/dist/stage/chunk-3QCKGZYE.js +32 -0
  469. package/dist/stage/chunk-44P66WFA.js +1 -0
  470. package/dist/stage/chunk-4AM6FRR6.js +7 -0
  471. package/dist/stage/chunk-4QDE4SUK.js +1 -0
  472. package/dist/stage/chunk-4QESHV3U.js +1 -0
  473. package/dist/stage/chunk-4SG5QPHB.js +2 -0
  474. package/dist/stage/chunk-4T4UVCOC.js +1 -0
  475. package/dist/stage/chunk-4WUEPPG3.js +34 -0
  476. package/dist/stage/chunk-4YCN6UZ5.js +99 -0
  477. package/dist/stage/chunk-5V7ZY2AP.js +1 -0
  478. package/dist/stage/chunk-5VS5Y2VJ.js +6 -0
  479. package/dist/stage/chunk-5W4NO2ZD.js +62 -0
  480. package/dist/stage/chunk-65CRNICM.js +1 -0
  481. package/dist/stage/chunk-66MULO7F.js +5 -0
  482. package/dist/stage/chunk-6COFQTBS.js +162 -0
  483. package/dist/stage/chunk-6VZG3M3I.js +8 -0
  484. package/dist/stage/chunk-7HVDH43T.js +1 -0
  485. package/dist/stage/chunk-7JLJN4EZ.js +8 -0
  486. package/dist/stage/chunk-7QDSP4LN.js +1 -0
  487. package/dist/stage/chunk-7R6OQAO3.js +1 -0
  488. package/dist/stage/chunk-7VTTHZKW.js +7 -0
  489. package/dist/stage/chunk-ATHR5KEN.js +10 -0
  490. package/dist/stage/chunk-B6R5LTP2.js +36 -0
  491. package/dist/stage/chunk-BD4WE264.js +1 -0
  492. package/dist/stage/chunk-BONANU47.js +206 -0
  493. package/dist/stage/chunk-BTVW7OFK.js +89 -0
  494. package/dist/stage/chunk-BUTJIDHG.js +8 -0
  495. package/dist/stage/chunk-C2IPYMML.js +84 -0
  496. package/dist/stage/chunk-C54FTPPV.js +9 -0
  497. package/dist/stage/chunk-C6LOUF2Z.js +90 -0
  498. package/dist/stage/chunk-CFF3PILO.js +339 -0
  499. package/dist/stage/chunk-CI2FQ2JY.js +9 -0
  500. package/dist/stage/chunk-CW5O4RV7.js +12 -0
  501. package/dist/stage/chunk-CYABNQYD.js +1 -0
  502. package/dist/stage/chunk-D7FFA4NS.js +15 -0
  503. package/dist/stage/chunk-DUNNXU6Z.js +8 -0
  504. package/dist/stage/chunk-E3E4Q6JF.js +6 -0
  505. package/dist/stage/chunk-EB3U3LH7.js +9 -0
  506. package/dist/stage/chunk-EGSZ736B.js +8 -0
  507. package/dist/stage/chunk-EOBXW5VQ.js +2 -0
  508. package/dist/stage/chunk-ERZC3B7Y.js +11 -0
  509. package/dist/stage/chunk-ESDOOBIH.js +11 -0
  510. package/dist/stage/chunk-EVU4QAL4.js +178 -0
  511. package/dist/stage/chunk-EVVZI2NY.js +39 -0
  512. package/dist/stage/chunk-FBKAZUKD.js +39 -0
  513. package/dist/stage/chunk-FDVKYQJN.js +1 -0
  514. package/dist/stage/chunk-FGPVYHVR.js +5 -0
  515. package/dist/stage/chunk-FHUD4AZC.js +1 -0
  516. package/dist/stage/chunk-FKUJ2DMY.js +96 -0
  517. package/dist/stage/chunk-FNZGVIJV.js +1 -0
  518. package/dist/stage/chunk-GBYSEGYM.js +78 -0
  519. package/dist/stage/chunk-GCO4TDHX.js +1 -0
  520. package/dist/stage/chunk-GKTML2LG.js +10 -0
  521. package/dist/stage/chunk-GMDIHHXQ.js +11 -0
  522. package/dist/stage/chunk-GOUNACI3.js +10 -0
  523. package/dist/stage/chunk-GXAYATPF.js +3 -0
  524. package/dist/stage/chunk-H2K2DDXV.js +8 -0
  525. package/dist/stage/chunk-H3UJI6ZY.js +13 -0
  526. package/dist/stage/chunk-H6PUGCME.js +7 -0
  527. package/dist/stage/chunk-HNBUIMIG.js +1 -0
  528. package/dist/stage/chunk-HRZY2BJQ.js +10 -0
  529. package/dist/stage/chunk-HSPJGALW.js +30 -0
  530. package/dist/stage/chunk-IBYORHIP.js +25 -0
  531. package/dist/stage/chunk-IHF4EWTY.js +1 -0
  532. package/dist/stage/chunk-ISBRPNKI.js +1 -0
  533. package/dist/stage/chunk-IZ3OI3C2.js +2 -0
  534. package/dist/stage/chunk-JEFZAC2R.js +1 -0
  535. package/dist/stage/chunk-JFIGRDPO.js +1 -0
  536. package/dist/stage/chunk-JFVYBOOC.js +9 -0
  537. package/dist/stage/chunk-JGD4TUTQ.js +1 -0
  538. package/dist/stage/chunk-JO4BEHDH.js +4 -0
  539. package/dist/stage/chunk-JOWBS42C.js +1 -0
  540. package/dist/stage/chunk-JP3TM2TG.js +1 -0
  541. package/dist/stage/chunk-JVK2C52O.js +1 -0
  542. package/dist/stage/chunk-K4I76XBX.js +14 -0
  543. package/dist/stage/chunk-KA6CZZ4M.js +1 -0
  544. package/dist/stage/chunk-KESSJ36M.js +1 -0
  545. package/dist/stage/chunk-LKATEVRU.js +1 -0
  546. package/dist/stage/chunk-LS4EJ2EI.js +1 -0
  547. package/dist/stage/chunk-LUKJQC2X.js +70 -0
  548. package/dist/stage/chunk-LWULR3SM.js +1 -0
  549. package/dist/stage/chunk-LWVRFMKX.js +2 -0
  550. package/dist/stage/chunk-LXC4ZBPZ.js +1 -0
  551. package/dist/stage/chunk-M2UP255H.js +1 -0
  552. package/dist/stage/chunk-MAPPXUZQ.js +231 -0
  553. package/dist/stage/chunk-MBMPW7Z5.js +1 -0
  554. package/dist/stage/chunk-MD3HMMTK.js +1 -0
  555. package/dist/stage/chunk-MLPCUIKR.js +17 -0
  556. package/dist/stage/chunk-MNQIRPDQ.js +8 -0
  557. package/dist/stage/chunk-MRG7MJVS.js +1 -0
  558. package/dist/stage/chunk-MU6EXW72.js +10 -0
  559. package/dist/stage/chunk-MVU2X6LU.js +4 -0
  560. package/dist/stage/chunk-N6UA5CZV.js +36 -0
  561. package/dist/stage/chunk-NLZIT2TJ.js +7 -0
  562. package/dist/stage/chunk-NOJR3J7M.js +1 -0
  563. package/dist/stage/chunk-NT7ARDOL.js +1 -0
  564. package/dist/stage/chunk-NWOGMPZH.js +1 -0
  565. package/dist/stage/chunk-NXE4KMG3.js +40 -0
  566. package/dist/stage/chunk-O4YCZXD2.js +257 -0
  567. package/dist/stage/chunk-OAJZ7HLK.js +1 -0
  568. package/dist/stage/chunk-OCFCFASO.js +1 -0
  569. package/dist/stage/chunk-ODGPG5RY.js +7 -0
  570. package/dist/stage/chunk-ODUEA52Q.js +3 -0
  571. package/dist/stage/chunk-OGDJ3FCI.js +1 -0
  572. package/dist/stage/chunk-OLDJ55TT.js +1 -0
  573. package/dist/stage/chunk-OOCL4ATI.js +2 -0
  574. package/dist/stage/chunk-OQEFDUDV.js +1 -0
  575. package/dist/stage/chunk-OQWVEWG7.js +4 -0
  576. package/dist/stage/chunk-OUIX6BGK.js +1 -0
  577. package/dist/stage/chunk-OV7OZYUO.js +7 -0
  578. package/dist/stage/chunk-PFGDY33O.js +1 -0
  579. package/dist/stage/chunk-PFJDUJB3.js +139 -0
  580. package/dist/stage/chunk-PGEW76ER.js +1 -0
  581. package/dist/stage/chunk-PP76TAQX.js +32 -0
  582. package/dist/stage/chunk-PTBOP4OT.js +2 -0
  583. package/dist/stage/chunk-PX2RVHCK.js +1 -0
  584. package/dist/stage/chunk-Q7K3PNAD.js +1 -0
  585. package/dist/stage/chunk-QDDPLZDB.js +1 -0
  586. package/dist/stage/chunk-QLGLZ77F.js +1 -0
  587. package/dist/stage/chunk-QOPFDFHI.js +1 -0
  588. package/dist/stage/chunk-QXT4KAEJ.js +1 -0
  589. package/dist/stage/chunk-R4YVZCIT.js +1 -0
  590. package/dist/stage/chunk-R6P6EHWA.js +62 -0
  591. package/dist/stage/chunk-RCH3OXBI.js +9 -0
  592. package/dist/stage/chunk-RHPE44I2.js +1 -0
  593. package/dist/stage/chunk-RJ2R4FVC.js +1 -0
  594. package/dist/stage/chunk-RJH2YVTD.js +1 -0
  595. package/dist/stage/chunk-RLWWW5OB.js +6 -0
  596. package/dist/stage/chunk-S3WO35Z7.js +120 -0
  597. package/dist/stage/chunk-S7ZGX6MW.js +1 -0
  598. package/dist/stage/chunk-SIAWX27B.js +1 -0
  599. package/dist/stage/chunk-SLG4X622.js +1 -0
  600. package/dist/stage/chunk-SLJRBC77.js +168 -0
  601. package/dist/stage/chunk-SRORWQJZ.js +1 -0
  602. package/dist/stage/chunk-STZTUIIF.js +2 -0
  603. package/dist/stage/chunk-SVQ6MWNV.js +9 -0
  604. package/dist/stage/chunk-TL3HLL2S.js +132 -0
  605. package/dist/stage/chunk-U3DOE6SF.js +24 -0
  606. package/dist/stage/chunk-UABQIZKW.js +6 -0
  607. package/dist/stage/chunk-UDK3R764.js +1 -0
  608. package/dist/stage/chunk-UFF4E54B.js +41 -0
  609. package/dist/stage/chunk-UFP5Q4AY.js +1 -0
  610. package/dist/stage/chunk-UMH2TSW2.js +72 -0
  611. package/dist/stage/chunk-UTASVNF5.js +10 -0
  612. package/dist/stage/chunk-UW7ML5ML.js +88 -0
  613. package/dist/stage/chunk-V3J7F6OP.js +1 -0
  614. package/dist/stage/chunk-VEHP5B5Q.js +5 -0
  615. package/dist/stage/chunk-VRXWB733.js +9 -0
  616. package/dist/stage/chunk-VVDHBBS5.js +5 -0
  617. package/dist/stage/chunk-VYFOH6FU.js +106 -0
  618. package/dist/stage/chunk-W3VZTLQS.js +3 -0
  619. package/dist/stage/chunk-W7WNRWTZ.js +8 -0
  620. package/dist/stage/chunk-WHUCV53C.js +1 -0
  621. package/dist/stage/chunk-WULMYHIF.js +1 -0
  622. package/dist/stage/chunk-X54EX7AW.js +9 -0
  623. package/dist/stage/chunk-X565ISZM.js +1 -0
  624. package/dist/stage/chunk-XGZMDECB.js +1 -0
  625. package/dist/stage/chunk-XHONC4RF.js +172 -0
  626. package/dist/stage/chunk-XIK4XQ6E.js +24 -0
  627. package/dist/stage/chunk-XJQQWFTE.js +1 -0
  628. package/dist/stage/chunk-XM4WOU3I.js +13 -0
  629. package/dist/stage/chunk-XM7Y5HP5.js +38 -0
  630. package/dist/stage/chunk-XNYYRGD5.js +292 -0
  631. package/dist/stage/chunk-XOYVR3SV.js +1 -0
  632. package/dist/stage/chunk-XQIW5HCE.js +1 -0
  633. package/dist/stage/chunk-YEWL7FUW.js +8 -0
  634. package/dist/stage/chunk-YI55PY3V.js +1 -0
  635. package/dist/stage/chunk-YM63HI6W.js +1 -0
  636. package/dist/stage/chunk-YNLGLU4P.js +9 -0
  637. package/dist/stage/chunk-YTNMNOWP.js +1 -0
  638. package/dist/stage/chunk-YV62XKTC.js +1 -0
  639. package/dist/stage/chunk-YVBA3QW6.js +1 -0
  640. package/dist/stage/chunk-Z2SY2HOC.js +1 -0
  641. package/dist/stage/chunk-ZBTCQEBK.js +10 -0
  642. package/dist/stage/chunk-ZCUFN74D.js +1 -0
  643. package/dist/stage/chunk-ZHOULXEJ.js +11 -0
  644. package/dist/stage/chunk-ZTRZIET2.js +1 -0
  645. package/dist/stage/index.html +1 -0
  646. package/dist/stage/stage.css +1 -1
  647. package/dist/stage/stage.js +1 -4383
  648. package/dist/ui/dev/dev-page.d.ts +1 -0
  649. package/dist/ui/dev/dev-page.js +2021 -0
  650. package/dist/ui/dev/dev-theme.d.ts +6 -0
  651. package/dist/ui/dev/dev-theme.js +67 -0
  652. package/dist/ui/dev/voice-gallery-page.d.ts +1 -0
  653. package/dist/ui/dev/voice-gallery-page.js +121 -0
  654. package/dist/ui/dev/voice-scenes.d.ts +21 -0
  655. package/dist/ui/dev/voice-scenes.js +30 -0
  656. package/dist/ui/dictation/en-box.d.ts +2 -0
  657. package/dist/ui/dictation/en-box.js +86 -0
  658. package/dist/ui/dictation/en-page.d.ts +1 -0
  659. package/dist/ui/dictation/en-page.js +484 -0
  660. package/dist/ui/dictation/page.d.ts +1 -0
  661. package/dist/ui/dictation/page.js +1084 -0
  662. package/dist/ui/dictation/parent-page.d.ts +1 -0
  663. package/dist/ui/dictation/parent-page.js +234 -0
  664. package/dist/ui/dictation/reel-mode.d.ts +1 -0
  665. package/dist/ui/dictation/reel-mode.js +87 -0
  666. package/dist/ui/dictation/reel-page.d.ts +1 -0
  667. package/dist/ui/dictation/reel-page.js +62 -0
  668. package/dist/ui/dictation/reel.d.ts +163 -0
  669. package/dist/ui/dictation/reel.js +436 -0
  670. package/dist/ui/dictation/ui.d.ts +44 -0
  671. package/dist/ui/dictation/ui.js +80 -0
  672. package/dist/ui/dictation/unlock.d.ts +7 -0
  673. package/dist/ui/dictation/unlock.js +16 -0
  674. package/dist/ui/kid/audio-client.d.ts +11 -0
  675. package/dist/ui/kid/audio-client.js +74 -0
  676. package/dist/ui/kid/board-mark-art.d.ts +37 -0
  677. package/dist/ui/kid/board-mark-art.js +5 -0
  678. package/dist/ui/kid/board-mark.d.ts +24 -0
  679. package/dist/ui/kid/board-mark.js +58 -0
  680. package/dist/ui/kid/home-tiles.d.ts +14 -0
  681. package/dist/ui/kid/home-tiles.js +44 -0
  682. package/dist/ui/kid/kid-log.d.ts +15 -0
  683. package/dist/ui/kid/kid-log.js +87 -0
  684. package/dist/ui/kid/kid-nav.d.ts +11 -0
  685. package/dist/ui/kid/kid-nav.js +22 -0
  686. package/dist/ui/kid/kid-page.d.ts +9 -0
  687. package/dist/ui/kid/kid-page.js +3684 -0
  688. package/dist/ui/kid/letters.d.ts +26 -0
  689. package/dist/ui/kid/letters.js +51 -0
  690. package/dist/ui/kid/photo-edit.d.ts +83 -0
  691. package/dist/ui/kid/photo-edit.js +106 -0
  692. package/dist/ui/kid/photo-ui.d.ts +23 -0
  693. package/dist/ui/kid/photo-ui.js +60 -0
  694. package/dist/ui/kid/reel.d.ts +419 -0
  695. package/dist/ui/kid/reel.js +648 -0
  696. package/dist/ui/kid/tianzige.d.ts +8 -0
  697. package/dist/ui/kid/tianzige.js +45 -0
  698. package/dist/ui/kid/tutor-face.d.ts +35 -0
  699. package/dist/ui/kid/tutor-face.js +84 -0
  700. package/dist/ui/kid/voice-ui.d.ts +70 -0
  701. package/dist/ui/kid/voice-ui.js +316 -0
  702. package/dist/ui/kid/voice-view.d.ts +71 -0
  703. package/dist/ui/kid/voice-view.js +75 -0
  704. package/dist/ui/kid/word-draw.d.ts +2 -0
  705. package/dist/ui/kid/word-draw.js +107 -0
  706. package/dist/ui/kid/word-emoji.d.ts +10 -0
  707. package/dist/ui/kid/word-emoji.js +68 -0
  708. package/dist/ui/kid/word-layout.d.ts +25 -0
  709. package/dist/ui/kid/word-layout.js +29 -0
  710. package/dist/ui/parent/parent-home-page.d.ts +1 -0
  711. package/dist/ui/parent/parent-home-page.js +722 -0
  712. package/dist/ui/parent/parent-page.d.ts +2 -0
  713. package/dist/ui/parent/parent-page.js +511 -0
  714. package/dist/ui/parent/parent-settings-page.d.ts +1 -0
  715. package/dist/ui/parent/parent-settings-page.js +133 -0
  716. package/dist/ui/parent/qr-page.d.ts +8 -0
  717. package/dist/ui/parent/qr-page.js +66 -0
  718. package/dist/ui/shared/brand.d.ts +38 -0
  719. package/dist/ui/shared/brand.js +53 -0
  720. package/dist/ui/shared/favicon.d.ts +12 -0
  721. package/dist/ui/shared/favicon.js +96 -0
  722. package/dist/ui/shared/icon.d.ts +9 -0
  723. package/dist/ui/shared/icon.js +35 -0
  724. package/dist/ui/shared/inline-lib.d.ts +1 -0
  725. package/dist/ui/shared/inline-lib.js +28 -0
  726. package/dist/ui/shared/logo.d.ts +31 -0
  727. package/dist/ui/shared/logo.js +43 -0
  728. package/dist/ui/shared/page-dom.d.ts +12 -0
  729. package/dist/ui/shared/page-dom.js +36 -0
  730. package/dist/ui/shared/png.d.ts +1 -0
  731. package/dist/ui/shared/png.js +45 -0
  732. package/dist/ui/shared/qr-svg.d.ts +3 -0
  733. package/dist/ui/shared/qr-svg.js +32 -0
  734. package/dist/ui/shared/qr.d.ts +14 -0
  735. package/dist/ui/shared/qr.js +281 -0
  736. package/dist/ui/shared/reel-dock.d.ts +22 -0
  737. package/dist/ui/shared/reel-dock.js +365 -0
  738. package/dist/ui/shared/tutor-color.d.ts +15 -0
  739. package/dist/ui/shared/tutor-color.js +47 -0
  740. package/dist/ui/talk/page.d.ts +6 -0
  741. package/dist/ui/talk/page.js +294 -0
  742. package/grades/grade-2/README.md +11 -0
  743. package/grades/grade-2/VALIDATION.md +41 -0
  744. package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273.md +157 -0
  745. 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
  746. 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
  747. 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
  748. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235.md +64 -0
  749. package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235./344/276/213/345/255/220.md +31 -0
  750. package/grades/grade-2/agents/chinese-tutor/activities//345/220/254/345/206/231.md +48 -0
  751. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240.md +79 -0
  752. package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  753. package/grades/grade-2/agents/chinese-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  754. package/grades/grade-2/agents/chinese-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +81 -0
  755. package/grades/grade-2/agents/chinese-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232./344/276/213/345/255/220.md +35 -0
  756. package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235.md +94 -0
  757. 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
  758. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240.md +82 -0
  759. package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  760. package/grades/grade-2/agents/chinese-tutor.md +59 -0
  761. package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276.md +149 -0
  762. 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
  763. package/grades/grade-2/agents/english-tutor/activities//345/220/254/345/206/231.md +47 -0
  764. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240.md +78 -0
  765. package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  766. package/grades/grade-2/agents/english-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
  767. package/grades/grade-2/agents/english-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +80 -0
  768. package/grades/grade-2/agents/english-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232./344/276/213/345/255/220.md +35 -0
  769. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240.md +86 -0
  770. package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  771. package/grades/grade-2/agents/english-tutor.md +57 -0
  772. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240.md +78 -0
  773. package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
  774. package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202.md +56 -0
  775. 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
  776. package/grades/grade-2/agents/math-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +80 -0
  777. package/grades/grade-2/agents/math-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232./344/276/213/345/255/220.md +35 -0
  778. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240.md +81 -0
  779. package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
  780. package/grades/grade-2/agents/math-tutor.md +51 -0
  781. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/index.json +44 -0
  782. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-1.mp3 +0 -0
  783. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-2.mp3 +0 -0
  784. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-3.mp3 +0 -0
  785. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-4.mp3 +0 -0
  786. package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-5.mp3 +0 -0
  787. package/grades/grade-2/examples/2026-10-27-pingjunfen/bake.json +1 -0
  788. package/grades/grade-2/examples/2026-10-27-pingjunfen/manifest.json +63 -0
  789. package/grades/grade-2/examples/2026-10-27-pingjunfen/scene.json +247 -0
  790. package/grades/grade-2/examples/2026-10-27-pingjunfen.md +40 -0
  791. package/grades/grade-2/examples/2026-10-27-pingjunfen.ts +26 -0
  792. package/grades/grade-2/examples//345/271/263/345/235/207/345/210/206./344/276/213/345/255/220.md +24 -0
  793. package/grades/grade-2/examples//346/225/260/345/255/246/345/271/263/345/235/207/345/210/206.md +42 -0
  794. package/grades/grade-2/validation/2026-10-27.json +4410 -0
  795. package/package.json +27 -15
  796. package/skills/chalk-cli/SKILL.md +62 -0
  797. package/skills/chalk-scene/SKILL.md +91 -0
  798. package/skills/chalk-teaching/SKILL.md +82 -0
  799. 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
  800. package/skills/chalk-teaching/models//345/207/221/345/215/201.md +7 -0
  801. package/skills/chalk-teaching/models//345/221/250/346/234/237/350/247/204/345/276/213.md +6 -0
  802. package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/345/242/236/345/207/217.md +6 -0
  803. 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
  804. 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
  805. package/skills/chalk-teaching/models//345/260/217/346/243/222/350/277/233/344/275/215/345/212/240.md +7 -0
  806. package/skills/chalk-teaching/models//345/260/217/346/243/222/351/200/200/344/275/215/345/207/217.md +6 -0
  807. package/skills/chalk-teaching/models//346/216/222/351/230/237/347/202/271/351/230/265.md +7 -0
  808. package/skills/chalk-teaching/models//346/227/266/351/227/264/346/225/260/350/275/264.md +6 -0
  809. package/skills/chalk-teaching/models//346/245/274/345/261/202/351/227/264/351/232/224/345/233/276.md +7 -0
  810. package/skills/chalk-teaching/models//347/240/264/345/215/201.md +7 -0
  811. package/skills/chalk-teaching/models//347/253/226/345/274/217/351/200/200/344/275/215.md +6 -0
  812. package/skills/chalk-teaching/models//347/272/277/346/256/265/345/233/276.md +7 -0
  813. package/skills/chalk-teaching/models-index.md +24 -0
  814. 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
  815. package/skills/chalk-teaching/references//350/257/264/346/230/216/346/226/207/344/273/266.md +102 -0
  816. package/skills/chalk-verify/SKILL.md +57 -0
  817. package/skills/chalk-verify/references//350/257/204/345/210/244/346/240/207/345/207/206.md +69 -0
  818. package/skills/cotutor-analyze/SKILL.md +106 -0
  819. package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +31 -0
  820. package/skills/cotutor-board/SKILL.md +373 -0
  821. package/skills/cotutor-board/references/README.md +38 -0
  822. package/skills/cotutor-board/references/canvas.md +68 -0
  823. package/skills/cotutor-board/references/choice.md +55 -0
  824. package/skills/cotutor-board/references/code.md +46 -0
  825. package/skills/cotutor-board/references/image.md +52 -0
  826. package/skills/cotutor-board/references/lecture.md +69 -0
  827. package/skills/cotutor-board/references/paint.md +77 -0
  828. package/skills/cotutor-board/references/photo.md +61 -0
  829. package/skills/cotutor-board/references/read.md +51 -0
  830. package/skills/cotutor-board/references/text.md +69 -0
  831. package/skills/cotutor-board/references/tianzige.md +78 -0
  832. package/skills/cotutor-board/references/word.md +91 -0
  833. package/skills/cotutor-home/SKILL.md +170 -0
  834. package/skills/cotutor-home/references/dictation.md +97 -0
  835. package/skills/cotutor-home/references/tutor.md +149 -0
  836. package/skills/cotutor-home/references//345/221/275/344/273/244.md +21 -0
  837. package/skills/cotutor-home/references//351/246/226/351/241/265/350/257/255/346/263/225.md +143 -0
  838. package/skills/cotutor-tune/SKILL.md +147 -0
  839. package/skills/cotutor-tune/references//345/255/227/346/256/265.md +53 -0
  840. package/skills/cotutor-tutor/SKILL.md +253 -0
  841. package/skills/cotutor-tutor/references//344/270/212/344/270/213/346/226/207/345/214/205.md +78 -0
  842. package/themes/default/kid.css +86 -0
  843. package/themes/default/theme.json +26 -0
  844. package/agents/chinese-tutor.md +0 -67
  845. package/agents/homework-tutor.md +0 -17
  846. package/agents/math-tutor.md +0 -68
  847. package/agents/planner.md +0 -18
  848. package/agents/reading-tutor.md +0 -65
  849. package/agents/scene-maker.md +0 -41
  850. package/dist/cards/canvas.d.ts +0 -22
  851. package/dist/cards/canvas.js +0 -65
  852. package/dist/cards/fill.d.ts +0 -14
  853. package/dist/cards/fill.js +0 -64
  854. package/dist/cards/index.d.ts +0 -48
  855. package/dist/cards/index.js +0 -115
  856. package/dist/cards/kind.js +0 -7
  857. package/dist/cards/scene.d.ts +0 -24
  858. package/dist/cards/scene.js +0 -67
  859. package/dist/cards/text.d.ts +0 -18
  860. package/dist/cards/text.js +0 -41
  861. package/dist/cli/cert.d.ts +0 -7
  862. package/dist/cli/cert.js +0 -36
  863. package/dist/cli/doctor.d.ts +0 -22
  864. package/dist/cli/doctor.js +0 -355
  865. package/dist/cli/init.js +0 -116
  866. package/dist/cli/main.js +0 -243
  867. package/dist/cli/serve.d.ts +0 -30
  868. package/dist/cli/serve.js +0 -56
  869. package/dist/cli/skeleton.d.ts +0 -39
  870. package/dist/cli/skeleton.js +0 -184
  871. package/dist/cli/skills.d.ts +0 -40
  872. package/dist/cli/skills.js +0 -170
  873. package/dist/cli/workspace.d.ts +0 -69
  874. package/dist/lib/agent-file.d.ts +0 -10
  875. package/dist/lib/agent-file.js +0 -16
  876. package/dist/lib/board.d.ts +0 -15
  877. package/dist/lib/board.js +0 -107
  878. package/dist/lib/context-pack.js +0 -55
  879. package/dist/lib/conversation.js +0 -88
  880. package/dist/lib/kid-board.d.ts +0 -148
  881. package/dist/lib/kid-board.js +0 -294
  882. package/dist/lib/kid-view.d.ts +0 -63
  883. package/dist/lib/kid-view.js +0 -93
  884. package/dist/lib/ledger.d.ts +0 -29
  885. package/dist/lib/run-plan.d.ts +0 -30
  886. package/dist/lib/run-plan.js +0 -32
  887. package/dist/lib/sections.d.ts +0 -12
  888. package/dist/lib/sections.js +0 -151
  889. package/dist/lib/stream.d.ts +0 -15
  890. package/dist/lib/stream.js +0 -69
  891. package/dist/lib/transcript.d.ts +0 -36
  892. package/dist/lib/transcript.js +0 -95
  893. package/dist/server/app.d.ts +0 -74
  894. package/dist/server/app.js +0 -406
  895. package/dist/server/kid-page.d.ts +0 -1
  896. package/dist/server/kid-page.js +0 -768
  897. package/dist/server/mock.js +0 -403
  898. package/dist/server/parent-page.d.ts +0 -8
  899. package/dist/server/parent-page.js +0 -393
  900. package/dist/server/runner.d.ts +0 -64
  901. package/dist/server/runner.js +0 -277
  902. package/dist/server/scene-props.d.ts +0 -16
  903. package/dist/server/scene-props.js +0 -39
  904. package/dist/server/store.d.ts +0 -43
  905. package/dist/server/store.js +0 -210
  906. package/dist/server/tts.d.ts +0 -51
  907. package/dist/server/tts.js +0 -99
  908. /package/dist/{cli → app/cli}/main.d.ts +0 -0
  909. /package/dist/{cards → board/cards}/choice.d.ts +0 -0
  910. /package/dist/{cards → board/cards}/code.d.ts +0 -0
  911. /package/dist/{cards → board/cards}/image.d.ts +0 -0
  912. /package/dist/{cards → board/cards}/read.d.ts +0 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * workspace骨架清单:init 建、doctor 查,同一张清单(两边各写一遍必然漂移)。
3
+ * workspace 布局:
4
+ * cotutor.json / .cotutor/shipped.json(出厂 hash)/ .agents/skills/(技能;.claude/skills 是指过去的链,给 Claude Code)
5
+ * agents/<name>.md(老师文件,拷自本包 grades/grade-<n>/agents/,是家长的;所有运行时都从这里拿老师正文)与 agents/<name>/(老师的家 = 会话 cwd)
6
+ * ledger/(产物账本)/ conversations/(对话索引与转录)
7
+ * vault 侧(《obsidian仓库设计.md》):档案 / 课程表 / 日记 / 教材 / 计划 / 参考,init 只建档案与参考 README(缺了才写)
8
+ */
9
+ import { readFileSync } from 'node:fs';
10
+ import { readFile, readdir } from 'node:fs/promises';
11
+ import { join } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { parseAgentFile } from "../../runtime/agent-file.js";
14
+ import { CONFIG_SCHEMA_FILE, DEFAULT_PORT, DICTATION_DEFAULT, cotutorJsonSchema } from "../../schema/index.js";
15
+ import { FACTORY_API_RUNTIMES } from "../../brain/index.js";
16
+ import { DEFAULT_GRADE, PACKAGE_GRADES_DIR } from "./grades.js";
17
+ import { mkdir, writeFile } from 'node:fs/promises';
18
+ export const DIRS = ['agents', 'ledger', 'conversations', 'bundles'];
19
+ export const LEDGER_FILES = ['ledger/artifacts.jsonl'];
20
+ /** 默认年级的出厂老师目录;workspace 的操作用 workspaceGradePack 选来源 */
21
+ export const PACKAGE_AGENTS_DIR = join(PACKAGE_GRADES_DIR, `grade-${DEFAULT_GRADE}`, 'agents');
22
+ /** 本包版本(出厂件的 hash 记录带它,升级时知道基于哪版) */
23
+ export const PACKAGE_VERSION = JSON.parse(readFileSync(fileURLToPath(new URL('../../../package.json', import.meta.url)), 'utf8')).version;
24
+ export async function shippedAgents(dir = PACKAGE_AGENTS_DIR) {
25
+ const out = [];
26
+ for (const f of (await readdir(dir)).filter((f) => f.endsWith('.md')).sort()) {
27
+ const file = join(dir, f);
28
+ const { frontmatter } = parseAgentFile(await readFile(file, 'utf8'));
29
+ if (frontmatter.name)
30
+ out.push({ name: frontmatter.name, file, description: frontmatter.description ?? '' });
31
+ }
32
+ return out;
33
+ }
34
+ export const GITIGNORE = `# 转录日志体积大、可从对话索引重建关键信息;要留全档就删掉下面这行
35
+ conversations/**/*.log
36
+ # 配音可重新合成
37
+ conversations/**/*.mp3
38
+ # 回放(cotutor replay)是调提示词与 vault 时的对照,不是孩子的对话
39
+ evals/
40
+ # 做好的课(课包、视频课)与课包截图:体积大,源在家长做课的地方
41
+ bundles/
42
+ lectures/
43
+ snaps/
44
+ # 口语课(孩子的原声、照片)
45
+ talk/
46
+ # 作业照片(孩子在老师页上拍的;paths.captures):体积大、只是这一轮的素材,认出的文字在日记里
47
+ captures/
48
+ # 家长在 workspace 里用 Claude Code 时它的个人设置
49
+ .claude/settings.local.json
50
+ # .cotutor/ 是机器文件(板书写法缓存、配音缓存、二维码、日志),只留出厂 hash 与 schema
51
+ .cotutor/*
52
+ !.cotutor/shipped.json
53
+ !.cotutor/cotutor.schema.json
54
+ node_modules/
55
+ .DS_Store
56
+ `;
57
+ /** 档案模板(paths.profile,缺了才写):cotutor: profile 的那篇,原文整篇进每个话题的第一条 */
58
+ export function profileTemplate(name) {
59
+ return `---
60
+ cotutor: profile
61
+ nickname: ${name}
62
+ birthday:
63
+ school_start:
64
+ city:
65
+ ---
66
+
67
+ (这篇是孩子的档案,文件名、放哪都行,认的是上面的 cotutor: profile。school_start 写读一年级的年月,如 2025-09,老师据此知道现在是几年级哪个学期。)
68
+
69
+ (下面写孩子的情况:性格、喜欢什么、要避开什么。每位老师每个话题开头都会整篇读到。)
70
+ `;
71
+ }
72
+ /** 参考目录的 README(缺了才写) */
73
+ export const REFERENCE_README = `# 参考
74
+
75
+ 这里放政策与你自己的笔记:讲某类题的偏好、薄弱点、忌讳、按题型整理的东西——随便建,机器只读不写。
76
+ 让老师看到的办法:在档案或这位老师的入口文件(\`cotutor: subject\` 的那篇)里链过去(\`[[找规律填数]]\`);老师拿到路径,要用时自己读。
77
+ `;
78
+ /**
79
+ * 家长自己加老师时的文件模板:和出厂老师一样只有人设与这一科的做法;
80
+ * 公共的守则(上下文包、三种回复、记忆段、不变的规矩)在机器技能 cotutor-tutor,应用每个话题第一条放进上下文包。
81
+ */
82
+ export function tutorTemplate(t) {
83
+ const what = t.subject ? `${t.subject}的事` : '孩子问的事';
84
+ const subject = t.subject ?? '这一科';
85
+ return `---
86
+ name: ${t.name}
87
+ description: ${t.description ?? `${t.display}。${what}都找它;随口问的一两句答完,要讲的在板书上一节一节讲`}
88
+ maxTurns: 40
89
+ permissionMode: bypassPermissions
90
+ ---
91
+ 你是这个家的${t.display},对面是一个孩子。(在这里写这位老师的性子和讲法,一两句:比如「说话慢一点,爱打比方」。)
92
+
93
+ 上下文包怎么看、三种回复、记忆段、不变的规矩,在每个话题第一条的 \`<cotutor-rules>\` 里,照着做;这里只写${t.display}自己的。
94
+
95
+ ## ${subject}
96
+
97
+ (下面几节写这一科特有的做法,一条一句。只写对哪个孩子、哪个学期都成立的;关于这个孩子、这学期的,写进 vault 里这一科的入口文件。用不上的小节删掉。)
98
+
99
+ ### 讲之前
100
+
101
+ (要对一下什么、教材里查什么。)
102
+
103
+ ### 讲
104
+
105
+ (这一科怎么讲、什么内容用哪种卡。)
106
+
107
+ ### 练
108
+
109
+ (一节末尾怎么问、用哪种卡。)
110
+
111
+ ### 孩子这样说时
112
+
113
+ (孩子常见的说法或答偏了,怎么接。)
114
+ `;
115
+ }
116
+ /** 出厂老师的条目;cards = 板书写法里讲哪几种卡(《卡片协议.md》「谁拿到哪些卡」,2026-10-07),text 总在;
117
+ * 不写 avatar:三门主科用包里的出厂头像(src/app/http/avatars.ts) */
118
+ const TUTOR_DEFAULTS = {
119
+ // 数学多想一会儿:算错的代价大(别的老师用缺省 low);走 qwen3.8-max(同语文老师)。运行时 api = 应用直连百炼(2026-10-31 起出厂缺省)
120
+ 'math-tutor': { display: '数学老师', subject: '数学', runtime: 'api', cards: ['text', 'choice', 'image', 'lecture', 'canvas', 'code'], policy: { effort: 'medium' } },
121
+ // 画图卡(paint)不在这里:只在「你说我画」activity 的话题里有(agents/chinese-tutor/activities/你说我画.md 头上的 cards)
122
+ // 语文老师走 qwen3.8-max(你说我画、看图说话两套 activity eval 在它上面验证;2026-10-31 Ray 上 API 与 Qwen Code 对照过)
123
+ 'chinese-tutor': { display: '语文老师', subject: '语文', runtime: 'api', cards: ['text', 'read', 'choice', 'image', 'tianzige', 'lecture', 'canvas'] },
124
+ // 英语也走 api(qwen3.8-max):2026-10-31 api-flash 真跑英语四个 activity,13 次里 5 次第一轮只出一张拍照卡、没有讲稿(实时页嘴没话可念);max 在 Ray 上都过。
125
+ // 想省钱改 api-flash,先跑 activity eval。medium 是 2026-10-27 给 flash 加的(low 偶尔只出卡或念规则,详见年级教学包验证记录)
126
+ 'english-tutor': { display: '英语老师', subject: '英语', runtime: 'api', cards: ['text', 'read', 'choice', 'image', 'word', 'lecture'], policy: { effort: 'medium' } },
127
+ };
128
+ /** cotutor.json 模板:只在文件不存在时写入;政策文件永不自动重建或覆盖(家长的决定不由机器代做)。 */
129
+ export function configTemplate(input) {
130
+ const tutors = {};
131
+ for (const a of input.tutors) {
132
+ const p = TUTOR_DEFAULTS[a.name];
133
+ tutors[a.name] = p
134
+ ? { display: p.display, ...(p.subject ? { subject: p.subject } : {}), enabled: p.enabled ?? true, ...(p.hidden ? { hidden: true } : {}), ...(p.runtime ? { runtime: p.runtime } : {}), ...(p.cards ? { cards: p.cards } : {}), ...(p.policy ? { policy: p.policy } : {}) }
135
+ : { display: a.name, enabled: true };
136
+ }
137
+ const cfg = {
138
+ $schema: CONFIG_SCHEMA_FILE,
139
+ version: 1,
140
+ title: input.name ? `${input.name}的老师们` : 'cotutor',
141
+ kid: { slug: input.slug, ...(input.name ? { name: input.name } : {}) },
142
+ server: { port: input.port ?? DEFAULT_PORT },
143
+ paths: {},
144
+ policyDefaults: {},
145
+ tutors,
146
+ // 缺省 api:应用直连百炼,家长端「首页」填一次按量 key + 业务空间 id 就能用(2026-10-31);2026-11-02 起只有 API 运行时
147
+ runtimes: { default: 'api', ...FACTORY_API_RUNTIMES },
148
+ // 听写的拍照认词:模型与挑词要求(prompt 一行一个字符串)写进文件,家长看得见、改得动
149
+ dictation: DICTATION_DEFAULT,
150
+ // 字段说明不写在这里:一写进去就冻住(政策文件永不覆盖),$schema 指的 schema 文件每次 init / upgrade 从 zod 的 .describe() 刷新
151
+ _note: '一孩一 workspace 的政策文件,家长改这里,机器不覆盖(写坏了靠 git 回退,cotutor doctor 可体检);每个字段的说明在 $schema 指的 .cotutor/cotutor.schema.json,编辑器里悬停就能看到。',
152
+ };
153
+ return `${JSON.stringify(cfg, null, 2)}\n`;
154
+ }
155
+ /** 把 JSON Schema 写进 workspace(机器文件,每次 init / upgrade 都刷新);板书语法表出厂成技能 cotutor-board,见 skills.ts `writeBoardSkill` */
156
+ export async function writeSchemaFile(root) {
157
+ const file = join(root, CONFIG_SCHEMA_FILE);
158
+ await mkdir(join(root, '.cotutor'), { recursive: true });
159
+ await writeFile(file, `${JSON.stringify(cotutorJsonSchema(), null, 2)}\n`);
160
+ return file;
161
+ }
@@ -0,0 +1,59 @@
1
+ import { BOARD_SKILL } from '../../board/cards/docs.ts';
2
+ import { ANALYZE_SKILL } from '../skills/analyze-doc.ts';
3
+ import { TUNE_SKILL } from '../skills/tune-doc.ts';
4
+ import { HOME_SKILL } from '../skills/home-doc.ts';
5
+ import { TUTOR_SKILL } from '../../runtime/context/tutor-rules.ts';
6
+ export { ANALYZE_SKILL, BOARD_SKILL, HOME_SKILL, TUNE_SKILL, TUTOR_SKILL };
7
+ export interface ShippedSkill {
8
+ name: string;
9
+ /** 机器件:每次 init / upgrade 都按包里的覆盖,不认家长的改动 */
10
+ machine?: boolean;
11
+ }
12
+ export declare const SHIPPED_SKILLS: readonly ShippedSkill[];
13
+ /**
14
+ * 不再出厂的技能:upgrade 时 workspace 里还有(出厂记录里有它)就删掉,免得编程助手照旧技能干活。
15
+ * 机器件(machine)向来不认家长的改动,照删;别的家长改过就留着,只是不再记在出厂清单里。
16
+ * cotutor-vault(2026-10-30,机器件):老师从没读过它(孩子的话不带工具,记账那条消息自带写法),要紧的几句并进了守则 cotutor-tutor。
17
+ * drawtell-*(2026-10-31):drawtell 并进本包,改名 chalk-*,命令是 cotutor chalk
18
+ */
19
+ export declare const RETIRED_SKILLS: readonly ShippedSkill[];
20
+ export type ShippedSkillName = string;
21
+ /** 本包自带的技能目录(仓库检出与 npm 安装都在包根 skills/) */
22
+ export declare const PACKAGE_SKILLS_DIR: string;
23
+ /** 这个技能在包里的目录 */
24
+ export declare function skillSourceDir(skill: ShippedSkill): string;
25
+ /** 一个目录的内容 hash:相对路径 + 内容,按路径排序 */
26
+ export declare function dirHash(dir: string): Promise<string>;
27
+ export type SkillState = 'latest' | 'upgradable' | 'custom' | 'untracked' | 'missing';
28
+ export interface SkillStatus {
29
+ name: ShippedSkillName;
30
+ state: SkillState;
31
+ dir: string;
32
+ basedOn?: string;
33
+ machine: boolean;
34
+ }
35
+ export declare function skillDir(root: string, name: string): string;
36
+ export declare function skillStatuses(root: string): Promise<SkillStatus[]>;
37
+ export interface SkillStep {
38
+ item: string;
39
+ action: 'created' | 'exists' | 'kept' | 'replaced' | 'removed';
40
+ note?: string;
41
+ }
42
+ /** init 用:缺的拷,有的不动;机器件每次按包里的刷 */
43
+ export declare function installSkills(root: string): Promise<SkillStep[]>;
44
+ export interface SkillUpgradeStep {
45
+ name: string;
46
+ action: 'upgraded' | 'latest' | 'kept-custom' | 'installed' | 'retired';
47
+ basedOn?: string;
48
+ machine?: boolean;
49
+ }
50
+ /** upgrade 用:latest 跳过;upgradable 换新(机器件改过也换);custom / untracked 保留只报;缺的补;不再出厂的删(改过的留) */
51
+ export declare function upgradeSkills(root: string): Promise<SkillUpgradeStep[]>;
52
+ /** Claude Code 只认 .claude/skills(Codex、Qwen Code 认 .agents/skills):在那里放一条相对链,两边看到的是同一份 */
53
+ export declare const CLAUDE_SKILLS_LINK = ".claude/skills";
54
+ /**
55
+ * init / upgrade 用:没有就建链;已经是链不动;是实体目录(老 workspace 没搬完)不碰,报一声。
56
+ * Windows 上建目录联接(junction):符号链接要「创建符号链接」权限,家长平常开的终端没有(UAC 拿掉了,开发者模式也多半没开)。
57
+ * 联接读回来是绝对路径,所以按指到哪儿比、不按字面比。还是建不了就跳过:这条链只给在 workspace 里用 Claude Code 的人,cotutor 自己不读它。
58
+ */
59
+ export declare function linkClaudeSkills(root: string): Promise<SkillStep>;
@@ -0,0 +1,199 @@
1
+ /**
2
+ * 出厂 skill:与老师文件同一套「拷不链」机制——init 拷进 workspace 的 .agents/skills/<name>/,hash 记 .cotutor/shipped.json 的 skills,
3
+ * (2026-10-30 从 .claude/skills/ 挪来:Codex、Qwen Code 认 .agents/skills;Claude Code 只认 .claude/skills,那里是一条指过来的链,见 linkClaudeSkills。)
4
+ * 出厂表 SHIPPED_SKILLS 每项带 machine 标记(2026-09-15,照 hyperframes 的 skills/ 目录),都在本包根 skills/<name>/(进 npm files;
5
+ * cotutor-board 整个、其余几个的 references/ 是 scripts/gen-skills.ts 生成后入库的,tests/skills.test.ts 断言一致):
6
+ * - machine: true 的是机器件(cotutor-tutor / cotutor-board / cotutor-analyze / cotutor-tune / cotutor-home:它们和解析器、契约、CLI 要一起变),init / upgrade 每次按包里的覆盖、家长改了也刷,状态只有 latest / upgradable;
7
+ * 其余拷进来就是家长的:upgrade 没改过的换新、改过的报 diff 保留(custom / untracked)。chalk-* 四个是做课包的(2026-10-31 随 drawtell 并进来,原名 drawtell-*)。
8
+ */
9
+ import { createHash } from 'node:crypto';
10
+ import { cp, lstat, mkdir, readFile, readdir, readlink, rm, symlink } from 'node:fs/promises';
11
+ import { dirname, join, relative, resolve } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { BOARD_SKILL } from "../../board/cards/docs.js";
14
+ import { ANALYZE_SKILL } from "../skills/analyze-doc.js";
15
+ import { TUNE_SKILL } from "../skills/tune-doc.js";
16
+ import { HOME_SKILL } from "../skills/home-doc.js";
17
+ import { TUTOR_SKILL } from "../../runtime/context/tutor-rules.js";
18
+ import { SKILLS_DIR } from "../../schema/index.js";
19
+ export { ANALYZE_SKILL, BOARD_SKILL, HOME_SKILL, TUNE_SKILL, TUTOR_SKILL };
20
+ import { PACKAGE_VERSION } from "./skeleton.js";
21
+ import { readManifest, writeManifest } from "./tutors.js";
22
+ export const SHIPPED_SKILLS = [
23
+ { name: TUTOR_SKILL, machine: true },
24
+ { name: BOARD_SKILL, machine: true },
25
+ { name: ANALYZE_SKILL, machine: true },
26
+ { name: TUNE_SKILL, machine: true },
27
+ { name: HOME_SKILL, machine: true },
28
+ { name: 'chalk-scene' },
29
+ { name: 'chalk-teaching' },
30
+ { name: 'chalk-cli' },
31
+ { name: 'chalk-verify' },
32
+ ];
33
+ /**
34
+ * 不再出厂的技能:upgrade 时 workspace 里还有(出厂记录里有它)就删掉,免得编程助手照旧技能干活。
35
+ * 机器件(machine)向来不认家长的改动,照删;别的家长改过就留着,只是不再记在出厂清单里。
36
+ * cotutor-vault(2026-10-30,机器件):老师从没读过它(孩子的话不带工具,记账那条消息自带写法),要紧的几句并进了守则 cotutor-tutor。
37
+ * drawtell-*(2026-10-31):drawtell 并进本包,改名 chalk-*,命令是 cotutor chalk
38
+ */
39
+ export const RETIRED_SKILLS = [{ name: 'cotutor-vault', machine: true }, { name: 'drawtell-scene' }, { name: 'drawtell-teaching' }, { name: 'drawtell-cli' }, { name: 'drawtell-verify' }];
40
+ /** 本包自带的技能目录(仓库检出与 npm 安装都在包根 skills/) */
41
+ export const PACKAGE_SKILLS_DIR = fileURLToPath(new URL('../../../skills/', import.meta.url));
42
+ /** 这个技能在包里的目录 */
43
+ export function skillSourceDir(skill) {
44
+ return join(PACKAGE_SKILLS_DIR, skill.name);
45
+ }
46
+ /** 一个目录的内容 hash:相对路径 + 内容,按路径排序 */
47
+ export async function dirHash(dir) {
48
+ const files = [];
49
+ const walk = async (d) => {
50
+ for (const e of (await readdir(d, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
51
+ const p = join(d, e.name);
52
+ if (e.isDirectory())
53
+ await walk(p);
54
+ else if (e.isFile())
55
+ files.push(p);
56
+ }
57
+ };
58
+ await walk(dir);
59
+ const h = createHash('sha256');
60
+ for (const f of files.sort()) {
61
+ h.update(relative(dir, f));
62
+ h.update('\0');
63
+ h.update(await readFile(f));
64
+ h.update('\0');
65
+ }
66
+ return `sha256:${h.digest('hex')}`;
67
+ }
68
+ export function skillDir(root, name) {
69
+ return join(root, SKILLS_DIR, name);
70
+ }
71
+ async function readState(root, skill, manifest) {
72
+ const { name } = skill;
73
+ const base = { name, machine: Boolean(skill.machine) };
74
+ const dir = skillDir(root, name);
75
+ const st = await lstat(dir).catch(() => null);
76
+ if (!st?.isDirectory())
77
+ return { ...base, state: 'missing', dir };
78
+ const rec = manifest.skills?.[name];
79
+ const mine = await dirHash(dir);
80
+ const shipped = await dirHash(skillSourceDir(skill)).catch(() => null);
81
+ if (shipped && mine === shipped)
82
+ return { ...base, state: 'latest', dir, basedOn: rec?.version };
83
+ // 机器件不认家长的改动:和包里不一样就是该换
84
+ if (skill.machine)
85
+ return { ...base, state: 'upgradable', dir, basedOn: rec?.version };
86
+ if (rec && rec.hash === mine)
87
+ return { ...base, state: 'upgradable', dir, basedOn: rec.version };
88
+ return { ...base, state: rec ? 'custom' : 'untracked', dir, basedOn: rec?.version };
89
+ }
90
+ export async function skillStatuses(root) {
91
+ const manifest = await readManifest(root);
92
+ const out = [];
93
+ for (const skill of SHIPPED_SKILLS)
94
+ out.push(await readState(root, skill, manifest));
95
+ return out;
96
+ }
97
+ /** 整个目录换成包里的(先删再拷),hash 记进清单;顺手清旧位置 */
98
+ async function installOne(root, skill, src, manifest) {
99
+ const dir = skillDir(root, skill.name);
100
+ await rm(dir, { recursive: true, force: true });
101
+ await mkdir(dirname(dir), { recursive: true });
102
+ await cp(src, dir, { recursive: true });
103
+ manifest.skills ??= {};
104
+ manifest.skills[skill.name] = { hash: await dirHash(dir), version: PACKAGE_VERSION };
105
+ }
106
+ /** init 用:缺的拷,有的不动;机器件每次按包里的刷 */
107
+ export async function installSkills(root) {
108
+ const steps = [];
109
+ const manifest = await readManifest(root);
110
+ let touched = false;
111
+ for (const skill of SHIPPED_SKILLS) {
112
+ const { name } = skill;
113
+ const s = await readState(root, skill, manifest);
114
+ const src = skillSourceDir(skill);
115
+ const item = `${SKILLS_DIR}/${name}/`;
116
+ if (s.state === 'missing') {
117
+ await installOne(root, skill, src, manifest);
118
+ touched = true;
119
+ steps.push({ item, action: 'created', note: skill.machine ? '机器件,从包里生成的技能,别改' : '拷自本包' });
120
+ }
121
+ else if (skill.machine) {
122
+ await installOne(root, skill, src, manifest);
123
+ touched = true;
124
+ steps.push({ item, action: 'exists', note: s.state === 'latest' ? '已按本包刷新(机器件)' : '已按本包换新(机器件,不认改动)' });
125
+ }
126
+ else
127
+ steps.push({ item, action: 'exists', note: s.state === 'custom' ? `自定义(基于 ${s.basedOn})` : s.state === 'upgradable' ? '可升级(cotutor upgrade)' : s.state === 'untracked' ? '已有(没有出厂记录);升级时当自定义对待' : undefined });
128
+ }
129
+ if (touched)
130
+ await writeManifest(root, { ...manifest, version: PACKAGE_VERSION });
131
+ return steps;
132
+ }
133
+ /** upgrade 用:latest 跳过;upgradable 换新(机器件改过也换);custom / untracked 保留只报;缺的补;不再出厂的删(改过的留) */
134
+ export async function upgradeSkills(root) {
135
+ const steps = [];
136
+ const manifest = await readManifest(root);
137
+ for (const skill of SHIPPED_SKILLS) {
138
+ const { name } = skill;
139
+ const machine = Boolean(skill.machine);
140
+ const s = await readState(root, skill, manifest);
141
+ const src = skillSourceDir(skill);
142
+ if (s.state === 'latest')
143
+ steps.push({ name, action: 'latest', basedOn: s.basedOn, machine });
144
+ else if (s.state === 'missing') {
145
+ await installOne(root, skill, src, manifest);
146
+ steps.push({ name, action: 'installed', machine });
147
+ }
148
+ else if (s.state === 'upgradable') {
149
+ await installOne(root, skill, src, manifest);
150
+ steps.push({ name, action: 'upgraded', basedOn: s.basedOn, machine });
151
+ }
152
+ else
153
+ steps.push({ name, action: 'kept-custom', basedOn: s.basedOn, machine });
154
+ }
155
+ for (const { name, machine } of RETIRED_SKILLS) {
156
+ const rec = manifest.skills?.[name];
157
+ if (!rec)
158
+ continue;
159
+ const dir = skillDir(root, name);
160
+ delete manifest.skills[name];
161
+ // 家长改过的不删:那份已经是她的了,只是不再记在出厂清单里(机器件不算)
162
+ if (!machine && (await lstat(dir).catch(() => null))?.isDirectory() && (await dirHash(dir)) !== rec.hash) {
163
+ steps.push({ name, action: 'kept-custom', basedOn: rec.version });
164
+ continue;
165
+ }
166
+ await rm(dir, { recursive: true, force: true });
167
+ steps.push({ name, action: 'retired', machine: Boolean(machine) });
168
+ }
169
+ await writeManifest(root, { ...manifest, version: PACKAGE_VERSION });
170
+ return steps;
171
+ }
172
+ /** Claude Code 只认 .claude/skills(Codex、Qwen Code 认 .agents/skills):在那里放一条相对链,两边看到的是同一份 */
173
+ export const CLAUDE_SKILLS_LINK = '.claude/skills';
174
+ /**
175
+ * init / upgrade 用:没有就建链;已经是链不动;是实体目录(老 workspace 没搬完)不碰,报一声。
176
+ * Windows 上建目录联接(junction):符号链接要「创建符号链接」权限,家长平常开的终端没有(UAC 拿掉了,开发者模式也多半没开)。
177
+ * 联接读回来是绝对路径,所以按指到哪儿比、不按字面比。还是建不了就跳过:这条链只给在 workspace 里用 Claude Code 的人,cotutor 自己不读它。
178
+ */
179
+ export async function linkClaudeSkills(root) {
180
+ const link = join(root, CLAUDE_SKILLS_LINK);
181
+ const target = join('..', SKILLS_DIR);
182
+ const item = `${CLAUDE_SKILLS_LINK} → ${SKILLS_DIR}`;
183
+ const st = await lstat(link).catch(() => null);
184
+ if (st?.isSymbolicLink()) {
185
+ const to = await readlink(link);
186
+ const key = (p) => (process.platform === 'win32' ? p.toLowerCase() : p);
187
+ return key(resolve(dirname(link), to.replace(/^\\\\\?\\/, ''))) === key(resolve(root, SKILLS_DIR)) ? { item, action: 'exists' } : { item, action: 'kept', note: `已经是指向 ${to} 的链,没动` };
188
+ }
189
+ if (st)
190
+ return { item, action: 'kept', note: `${CLAUDE_SKILLS_LINK} 是实体目录,没建链:把里面的技能挪进 ${SKILLS_DIR}/、删掉它,再跑 cotutor upgrade` };
191
+ await mkdir(dirname(link), { recursive: true });
192
+ try {
193
+ await symlink(target, link, process.platform === 'win32' ? 'junction' : undefined);
194
+ }
195
+ catch (err) {
196
+ return { item, action: 'kept', note: `建不了链(${err.code ?? err}),跳过:只影响在 workspace 里用 Claude Code 看技能,cotutor 照常用` };
197
+ }
198
+ return { item, action: 'created', note: 'Claude Code 只认 .claude/skills,链到同一份' };
199
+ }
@@ -0,0 +1,52 @@
1
+ import { type ThemeManifest } from '../../schema/index.ts';
2
+ import { UsageError } from '../workspace.ts';
3
+ /** 本包自带的主题目录(仓库检出与 npm 安装都在包根 themes/) */
4
+ export declare const PACKAGE_THEMES_DIR: string;
5
+ export declare const SHIPPED_THEMES: readonly ["default"];
6
+ export declare function themeDir(root: string, name: string): string;
7
+ export declare class ThemeError extends UsageError {
8
+ readonly dir: string;
9
+ constructor(dir: string, message: string);
10
+ }
11
+ export interface LoadedTheme {
12
+ name: string;
13
+ dir: string;
14
+ manifest: ThemeManifest;
15
+ css: string;
16
+ }
17
+ /** 读一个主题目录:清单过契约、css 在;坏了抛 ThemeError(消息就是修复指南) */
18
+ export declare function readTheme(dir: string): Promise<LoadedTheme>;
19
+ /** 出厂主题(包里那份);包坏了是开发错误,直接抛 */
20
+ export declare function packageTheme(name?: string): Promise<LoadedTheme>;
21
+ export type ThemeState = 'latest' | 'upgradable' | 'custom' | 'untracked' | 'missing';
22
+ export interface ThemeStatus {
23
+ name: string;
24
+ state: ThemeState;
25
+ dir: string;
26
+ basedOn?: string;
27
+ /** 出厂件与否(自家加的主题 upgrade 不碰) */
28
+ shipped: boolean;
29
+ }
30
+ /** workspace 里所有主题的状态:出厂的 + themes/ 下自家建的 */
31
+ export declare function themeStatuses(root: string): Promise<ThemeStatus[]>;
32
+ export interface ThemeStep {
33
+ item: string;
34
+ action: 'created' | 'exists' | 'kept';
35
+ note?: string;
36
+ }
37
+ /** init 用:缺的拷,有的不动 */
38
+ export declare function installThemes(root: string): Promise<ThemeStep[]>;
39
+ export interface ThemeUpgradeStep {
40
+ name: string;
41
+ action: 'upgraded' | 'latest' | 'kept-custom' | 'installed';
42
+ basedOn?: string;
43
+ }
44
+ /** upgrade 用:latest 跳过;upgradable 换新;custom / untracked 保留只报;缺的补 */
45
+ export declare function upgradeThemes(root: string): Promise<ThemeUpgradeStep[]>;
46
+ export interface AddThemeResult {
47
+ name: string;
48
+ dir: string;
49
+ from: string;
50
+ }
51
+ /** cotutor add-theme <name> [--from <主题>]:拷一份(缺省 default)来改;清单里的 name 改成新名 */
52
+ export declare function addTheme(root: string, name: string, from?: string): Promise<AddThemeResult>;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * 主题(themes/<name>/theme.json + kid.css):孩子端板书的样子。样子的真相在主题里,不在卡的协议里。
3
+ * 出厂主题 default 在包根 themes/default/;init **拷贝**进 workspace 的 themes/default/(拷进来就是家长的,改了刷新就有),
4
+ * 目录 hash 记 .cotutor/shipped.json 的 themes,与老师文件 / skill 同一套:没改过的随 cotutor upgrade 换新,改过的报 diff 保留。
5
+ * 自家的主题(cotutor add-theme <name> 拷一份 default 来改,或直接建目录)永远 untracked,upgrade 不碰。
6
+ */
7
+ import { cp, lstat, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';
8
+ import { join } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { THEME_CSS_FILE, THEME_MANIFEST_FILE, THEME_NAME_RE, THEMES_DIR, ThemeManifestSchema, explainIssues } from "../../schema/index.js";
11
+ import { PACKAGE_VERSION } from "./skeleton.js";
12
+ import { dirHash } from "./skills.js";
13
+ import { readManifest, writeManifest } from "./tutors.js";
14
+ import { UsageError } from "../workspace.js";
15
+ /** 本包自带的主题目录(仓库检出与 npm 安装都在包根 themes/) */
16
+ export const PACKAGE_THEMES_DIR = fileURLToPath(new URL('../../../themes/', import.meta.url));
17
+ export const SHIPPED_THEMES = ['default'];
18
+ export function themeDir(root, name) {
19
+ return join(root, THEMES_DIR, name);
20
+ }
21
+ export class ThemeError extends UsageError {
22
+ dir;
23
+ constructor(dir, message) {
24
+ super(message);
25
+ this.name = 'ThemeError';
26
+ this.dir = dir;
27
+ }
28
+ }
29
+ /** 读一个主题目录:清单过契约、css 在;坏了抛 ThemeError(消息就是修复指南) */
30
+ export async function readTheme(dir) {
31
+ const mf = join(dir, THEME_MANIFEST_FILE);
32
+ let raw;
33
+ try {
34
+ raw = JSON.parse(await readFile(mf, 'utf8'));
35
+ }
36
+ catch (err) {
37
+ throw new ThemeError(dir, `${mf} 读不到或不是 JSON:${err instanceof Error ? err.message : String(err)}`);
38
+ }
39
+ const r = ThemeManifestSchema.safeParse(raw);
40
+ if (!r.success)
41
+ throw new ThemeError(dir, `${mf} 不合契约:\n${explainIssues(r.error.issues)}`);
42
+ let css;
43
+ try {
44
+ css = await readFile(join(dir, THEME_CSS_FILE), 'utf8');
45
+ }
46
+ catch {
47
+ throw new ThemeError(dir, `${join(dir, THEME_CSS_FILE)} 不在(主题的样式文件)`);
48
+ }
49
+ return { name: r.data.name, dir, manifest: r.data, css };
50
+ }
51
+ /** 出厂主题(包里那份);包坏了是开发错误,直接抛 */
52
+ export function packageTheme(name = 'default') {
53
+ return readTheme(join(PACKAGE_THEMES_DIR, name));
54
+ }
55
+ async function readState(root, name, manifest) {
56
+ const dir = themeDir(root, name);
57
+ const shipped = SHIPPED_THEMES.includes(name);
58
+ const st = await lstat(dir).catch(() => null);
59
+ if (!st?.isDirectory())
60
+ return { name, state: 'missing', dir, shipped };
61
+ if (!shipped)
62
+ return { name, state: 'untracked', dir, shipped };
63
+ const rec = manifest.themes?.[name];
64
+ const mine = await dirHash(dir);
65
+ const factory = await dirHash(join(PACKAGE_THEMES_DIR, name)).catch(() => null);
66
+ if (factory && mine === factory)
67
+ return { name, state: 'latest', dir, basedOn: rec?.version, shipped };
68
+ if (rec && rec.hash === mine)
69
+ return { name, state: 'upgradable', dir, basedOn: rec.version, shipped };
70
+ return { name, state: rec ? 'custom' : 'untracked', dir, basedOn: rec?.version, shipped };
71
+ }
72
+ /** workspace 里所有主题的状态:出厂的 + themes/ 下自家建的 */
73
+ export async function themeStatuses(root) {
74
+ const manifest = await readManifest(root);
75
+ const names = new Set(SHIPPED_THEMES);
76
+ for (const e of await readdir(join(root, THEMES_DIR), { withFileTypes: true }).catch(() => []))
77
+ if (e.isDirectory() && THEME_NAME_RE.test(e.name))
78
+ names.add(e.name);
79
+ const out = [];
80
+ for (const name of [...names].sort())
81
+ out.push(await readState(root, name, manifest));
82
+ return out;
83
+ }
84
+ async function installOne(root, name, manifest) {
85
+ const dir = themeDir(root, name);
86
+ await rm(dir, { recursive: true, force: true });
87
+ await mkdir(dir, { recursive: true });
88
+ await cp(join(PACKAGE_THEMES_DIR, name), dir, { recursive: true });
89
+ manifest.themes ??= {};
90
+ manifest.themes[name] = { hash: await dirHash(dir), version: PACKAGE_VERSION };
91
+ }
92
+ /** init 用:缺的拷,有的不动 */
93
+ export async function installThemes(root) {
94
+ const steps = [];
95
+ const manifest = await readManifest(root);
96
+ let touched = false;
97
+ for (const name of SHIPPED_THEMES) {
98
+ const s = await readState(root, name, manifest);
99
+ const item = `${THEMES_DIR}/${name}/`;
100
+ if (s.state === 'missing') {
101
+ await installOne(root, name, manifest);
102
+ touched = true;
103
+ steps.push({ item, action: 'created', note: '孩子端的主题(theme.json 槽的清单 + kid.css 样式),拷自本包,改了刷新就有' });
104
+ }
105
+ else
106
+ steps.push({ item, action: 'exists', note: s.state === 'custom' ? `自定义(基于 ${s.basedOn})` : s.state === 'upgradable' ? '可升级(cotutor upgrade)' : s.state === 'untracked' ? '已有(没有出厂记录);升级时当自定义对待' : undefined });
107
+ }
108
+ if (touched)
109
+ await writeManifest(root, { ...manifest, version: PACKAGE_VERSION });
110
+ return steps;
111
+ }
112
+ /** upgrade 用:latest 跳过;upgradable 换新;custom / untracked 保留只报;缺的补 */
113
+ export async function upgradeThemes(root) {
114
+ const manifest = await readManifest(root);
115
+ const steps = [];
116
+ for (const name of SHIPPED_THEMES) {
117
+ const s = await readState(root, name, manifest);
118
+ if (s.state === 'latest')
119
+ steps.push({ name, action: 'latest', basedOn: s.basedOn });
120
+ else if (s.state === 'missing') {
121
+ await installOne(root, name, manifest);
122
+ steps.push({ name, action: 'installed' });
123
+ }
124
+ else if (s.state === 'upgradable') {
125
+ await installOne(root, name, manifest);
126
+ steps.push({ name, action: 'upgraded', basedOn: s.basedOn });
127
+ }
128
+ else
129
+ steps.push({ name, action: 'kept-custom', basedOn: s.basedOn });
130
+ }
131
+ await writeManifest(root, { ...manifest, version: PACKAGE_VERSION });
132
+ return steps;
133
+ }
134
+ /** cotutor add-theme <name> [--from <主题>]:拷一份(缺省 default)来改;清单里的 name 改成新名 */
135
+ export async function addTheme(root, name, from = 'default') {
136
+ if (!THEME_NAME_RE.test(name))
137
+ throw new UsageError(`主题名只能是小写字母、数字、连字符:${name}`);
138
+ const dir = themeDir(root, name);
139
+ if (await lstat(dir).catch(() => null))
140
+ throw new UsageError(`${dir} 已经在了`);
141
+ const srcDir = (await lstat(themeDir(root, from)).catch(() => null))?.isDirectory() ? themeDir(root, from) : join(PACKAGE_THEMES_DIR, from);
142
+ const src = await readTheme(srcDir);
143
+ await mkdir(dir, { recursive: true });
144
+ await cp(srcDir, dir, { recursive: true });
145
+ const raw = JSON.parse(await readFile(join(dir, THEME_MANIFEST_FILE), 'utf8'));
146
+ await writeFile(join(dir, THEME_MANIFEST_FILE), `${JSON.stringify({ ...raw, name }, null, 2)}\n`);
147
+ return { name, dir, from: src.name };
148
+ }
@@ -0,0 +1,11 @@
1
+ export declare const TRAY_DOT: {
2
+ r: number;
3
+ cx: number;
4
+ };
5
+ /** 没在跑时 logo 的不透明度(#F3F3F3 上墨色对比度 3.3,#202020 上白色 5.8) */
6
+ export declare const TRAY_DIM = 0.55;
7
+ export declare const TRAY_WIN_SIZES: readonly [16, 20, 24, 32, 40, 48];
8
+ /** 文件名 → 内容:macOS 那几张 */
9
+ export declare function macTrayIcons(): Record<string, Buffer>;
10
+ /** 文件名 → 内容:Windows 那几张(<white|ink>-<ok|warn|bad>-<尺寸>.png、dot-<状态>.png) */
11
+ export declare function windowsTrayIcons(): Record<string, Buffer>;