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.
- package/LICENSE +249 -21
- package/NOTICE +42 -0
- package/README.md +115 -20
- package/avatars/chinese.webp +0 -0
- package/avatars/english.webp +0 -0
- package/avatars/math.webp +0 -0
- package/bin/cotutor.js +15 -5
- package/cards/canvas/card.css +8 -0
- package/cards/canvas/card.md +68 -0
- package/cards/choice/card.css +18 -0
- package/cards/choice/card.md +55 -0
- package/cards/code/card.css +5 -0
- package/cards/code/card.md +46 -0
- package/cards/dictation/card.css +10 -0
- package/cards/dictation/card.md +97 -0
- package/cards/image/card.css +10 -0
- package/cards/image/card.md +52 -0
- package/cards/lecture/card.css +9 -0
- package/cards/lecture/card.md +69 -0
- package/cards/paint/card.css +20 -0
- package/cards/paint/card.md +77 -0
- package/cards/photo/card.css +22 -0
- package/cards/photo/card.md +61 -0
- package/cards/read/card.css +6 -0
- package/cards/read/card.md +51 -0
- package/cards/text/card.css +3 -0
- package/cards/text/card.md +69 -0
- package/cards/tianzige/card.css +17 -0
- package/cards/tianzige/card.md +78 -0
- package/cards/tutor/card.css +79 -0
- package/cards/tutor/card.md +149 -0
- package/cards/word/card.css +24 -0
- package/cards/word/card.md +91 -0
- package/cards//346/235/277/344/271/246/346/200/216/344/271/210/345/206/231.md +159 -0
- package/dist/app/activity-eval-rules.d.ts +62 -0
- package/dist/app/activity-eval-rules.js +276 -0
- package/dist/app/activity-eval.d.ts +65 -0
- package/dist/app/activity-eval.js +159 -0
- package/dist/app/build.d.ts +11 -0
- package/dist/app/build.js +45 -0
- package/dist/app/cli/activities.d.ts +70 -0
- package/dist/app/cli/activities.js +196 -0
- package/dist/app/cli/cert.d.ts +12 -0
- package/dist/app/cli/cert.js +49 -0
- package/dist/app/cli/chalk/bake.d.ts +10 -0
- package/dist/app/cli/chalk/bake.js +58 -0
- package/dist/app/cli/chalk/browser.d.ts +16 -0
- package/dist/app/cli/chalk/browser.js +157 -0
- package/dist/app/cli/chalk/build.d.ts +14 -0
- package/dist/app/cli/chalk/build.js +100 -0
- package/dist/app/cli/chalk/dub.d.ts +51 -0
- package/dist/app/cli/chalk/dub.js +106 -0
- package/dist/app/cli/chalk/load-scene.d.ts +34 -0
- package/dist/app/cli/chalk/load-scene.js +117 -0
- package/dist/app/cli/chalk/main.d.ts +7 -0
- package/dist/app/cli/chalk/main.js +199 -0
- package/dist/app/cli/chalk/serve.d.ts +4 -0
- package/dist/app/cli/chalk/serve.js +28 -0
- package/dist/app/cli/chalk/snap.d.ts +65 -0
- package/dist/app/cli/chalk/snap.js +103 -0
- package/dist/app/cli/chalk/typecheck.d.ts +7 -0
- package/dist/app/cli/chalk/typecheck.js +51 -0
- package/dist/app/cli/doctor.d.ts +24 -0
- package/dist/app/cli/doctor.js +553 -0
- package/dist/app/cli/firewall.d.ts +24 -0
- package/dist/app/cli/firewall.js +79 -0
- package/dist/app/cli/grades.d.ts +14 -0
- package/dist/app/cli/grades.js +44 -0
- package/dist/{cli → app/cli}/init.d.ts +3 -1
- package/dist/app/cli/init.js +158 -0
- package/dist/app/cli/main.js +1038 -0
- package/dist/app/cli/migrate.d.ts +49 -0
- package/dist/app/cli/migrate.js +195 -0
- package/dist/app/cli/port-holder.d.ts +16 -0
- package/dist/app/cli/port-holder.js +34 -0
- package/dist/app/cli/port.d.ts +37 -0
- package/dist/app/cli/port.js +116 -0
- package/dist/app/cli/sandbox.d.ts +25 -0
- package/dist/app/cli/sandbox.js +166 -0
- package/dist/app/cli/serve-log.d.ts +13 -0
- package/dist/app/cli/serve-log.js +90 -0
- package/dist/app/cli/serve.d.ts +51 -0
- package/dist/app/cli/serve.js +168 -0
- package/dist/app/cli/service-windows.d.ts +50 -0
- package/dist/app/cli/service-windows.js +117 -0
- package/dist/app/cli/service.d.ts +138 -0
- package/dist/app/cli/service.js +429 -0
- package/dist/app/cli/shipped.d.ts +30 -0
- package/dist/app/cli/shipped.js +47 -0
- package/dist/app/cli/skeleton.d.ts +38 -0
- package/dist/app/cli/skeleton.js +161 -0
- package/dist/app/cli/skills.d.ts +59 -0
- package/dist/app/cli/skills.js +199 -0
- package/dist/app/cli/themes.d.ts +52 -0
- package/dist/app/cli/themes.js +148 -0
- package/dist/app/cli/tray-icons.d.ts +11 -0
- package/dist/app/cli/tray-icons.js +87 -0
- package/dist/app/cli/tray-ids.d.ts +6 -0
- package/dist/app/cli/tray-ids.js +6 -0
- package/dist/app/cli/tray-mac.d.ts +8 -0
- package/dist/app/cli/tray-mac.js +140 -0
- package/dist/app/cli/tray-run.d.ts +1 -0
- package/dist/app/cli/tray-run.js +33 -0
- package/dist/app/cli/tray-windows.d.ts +5 -0
- package/dist/app/cli/tray-windows.js +166 -0
- package/dist/app/cli/tray.d.ts +205 -0
- package/dist/app/cli/tray.js +618 -0
- package/dist/{cli → app/cli}/tutors.d.ts +15 -26
- package/dist/{cli → app/cli}/tutors.js +86 -110
- package/dist/app/cli/usage.d.ts +2 -0
- package/dist/app/cli/usage.js +35 -0
- package/dist/app/dictation/recognize.d.ts +18 -0
- package/dist/app/dictation/recognize.js +6 -0
- package/dist/app/dictation/route.d.ts +52 -0
- package/dist/app/dictation/route.js +511 -0
- package/dist/app/diff.d.ts +11 -0
- package/dist/app/diff.js +71 -0
- package/dist/app/http/access.d.ts +62 -0
- package/dist/app/http/access.js +180 -0
- package/dist/app/http/app.d.ts +241 -0
- package/dist/app/http/app.js +1159 -0
- package/dist/app/http/avatars.d.ts +17 -0
- package/dist/app/http/avatars.js +35 -0
- package/dist/app/http/dev-activities.d.ts +115 -0
- package/dist/app/http/dev-activities.js +193 -0
- package/dist/app/http/dev-overview.d.ts +108 -0
- package/dist/app/http/dev-overview.js +209 -0
- package/dist/app/http/dev-tutor-files.d.ts +80 -0
- package/dist/app/http/dev-tutor-files.js +151 -0
- package/dist/app/http/parent-home.d.ts +51 -0
- package/dist/app/http/parent-home.js +266 -0
- package/dist/app/http/parent-look.d.ts +2 -0
- package/dist/app/http/parent-look.js +151 -0
- package/dist/app/http/range.d.ts +9 -0
- package/dist/app/http/range.js +19 -0
- package/dist/app/http/raw-view.d.ts +117 -0
- package/dist/app/http/raw-view.js +149 -0
- package/dist/app/http/send-file.d.ts +7 -0
- package/dist/app/http/send-file.js +29 -0
- package/dist/{server → app/http}/stage.d.ts +9 -0
- package/dist/{server → app/http}/stage.js +34 -6
- package/dist/app/http/theme.d.ts +13 -0
- package/dist/app/http/theme.js +41 -0
- package/dist/app/http/voice-preview.d.ts +4 -0
- package/dist/app/http/voice-preview.js +34 -0
- package/dist/app/machine/bailian.d.ts +26 -0
- package/dist/app/machine/bailian.js +87 -0
- package/dist/app/mock/mock-live.d.ts +16 -0
- package/dist/app/mock/mock-live.js +140 -0
- package/dist/{server → app/mock}/mock.d.ts +38 -5
- package/dist/app/mock/mock.js +1125 -0
- package/dist/app/replay.d.ts +94 -0
- package/dist/app/replay.js +170 -0
- package/dist/app/skills/analyze-doc.d.ts +3 -0
- package/dist/app/skills/analyze-doc.js +47 -0
- package/dist/app/skills/home-doc.d.ts +5 -0
- package/dist/app/skills/home-doc.js +112 -0
- package/dist/app/skills/tune-doc.d.ts +3 -0
- package/dist/app/skills/tune-doc.js +80 -0
- package/dist/app/talk/list.d.ts +11 -0
- package/dist/app/talk/list.js +9 -0
- package/dist/app/talk/route.d.ts +16 -0
- package/dist/app/talk/route.js +142 -0
- package/dist/app/workspace.d.ts +63 -0
- package/dist/{cli → app}/workspace.js +100 -52
- package/dist/app/ws/route.d.ts +31 -0
- package/dist/app/ws/route.js +33 -0
- package/dist/app/ws/ws.d.ts +31 -0
- package/dist/app/ws/ws.js +169 -0
- package/dist/board/canvas-chat.d.ts +97 -0
- package/dist/board/canvas-chat.js +175 -0
- package/dist/board/card-guards.d.ts +15 -0
- package/dist/board/card-guards.js +38 -0
- package/dist/board/cards/canvas.d.ts +41 -0
- package/dist/board/cards/canvas.js +83 -0
- package/dist/{cards → board/cards}/choice.js +0 -12
- package/dist/{cards → board/cards}/code.js +0 -3
- package/dist/board/cards/dictation.d.ts +42 -0
- package/dist/board/cards/dictation.js +105 -0
- package/dist/board/cards/docs.d.ts +47 -0
- package/dist/board/cards/docs.js +152 -0
- package/dist/{cards → board/cards}/image.js +1 -10
- package/dist/board/cards/index.d.ts +62 -0
- package/dist/board/cards/index.js +144 -0
- package/dist/{cards → board/cards}/kind.d.ts +10 -4
- package/dist/board/cards/kind.js +9 -0
- package/dist/board/cards/lecture.d.ts +26 -0
- package/dist/board/cards/lecture.js +62 -0
- package/dist/board/cards/paint.d.ts +38 -0
- package/dist/board/cards/paint.js +85 -0
- package/dist/board/cards/photo.d.ts +15 -0
- package/dist/board/cards/photo.js +29 -0
- package/dist/{cards → board/cards}/read.js +1 -10
- package/dist/board/cards/text.d.ts +20 -0
- package/dist/board/cards/text.js +59 -0
- package/dist/board/cards/tianzige.d.ts +16 -0
- package/dist/board/cards/tianzige.js +64 -0
- package/dist/board/cards/tutor.d.ts +72 -0
- package/dist/board/cards/tutor.js +134 -0
- package/dist/board/cards/word.d.ts +20 -0
- package/dist/board/cards/word.js +76 -0
- package/dist/board/lecture.d.ts +100 -0
- package/dist/board/lecture.js +204 -0
- package/dist/board/paper.d.ts +20 -0
- package/dist/board/paper.js +76 -0
- package/dist/board/parse.d.ts +118 -0
- package/dist/board/parse.js +324 -0
- package/dist/board/presentation.d.ts +289 -0
- package/dist/board/presentation.js +613 -0
- package/dist/board/sections.d.ts +16 -0
- package/dist/board/sections.js +130 -0
- package/dist/brain/api-tools.d.ts +8 -0
- package/dist/brain/api-tools.js +191 -0
- package/dist/brain/api.d.ts +57 -0
- package/dist/brain/api.js +394 -0
- package/dist/brain/index.d.ts +97 -0
- package/dist/brain/index.js +11 -0
- package/dist/brain/log.d.ts +5 -0
- package/dist/brain/log.js +22 -0
- package/dist/brain/runtime.d.ts +30 -0
- package/dist/brain/runtime.js +23 -0
- package/dist/brain/stream-json.d.ts +16 -0
- package/dist/brain/stream-json.js +82 -0
- package/dist/brain/stream.d.ts +20 -0
- package/dist/brain/stream.js +70 -0
- package/dist/brain/transcript.d.ts +45 -0
- package/dist/brain/transcript.js +132 -0
- package/dist/brain/types.d.ts +99 -0
- package/dist/brain/types.js +14 -0
- package/dist/chalk/actions.d.ts +37 -0
- package/dist/chalk/actions.js +69 -0
- package/dist/chalk/bundle.d.ts +26 -0
- package/dist/chalk/bundle.js +69 -0
- package/dist/chalk/check.d.ts +28 -0
- package/dist/chalk/check.js +291 -0
- package/dist/chalk/circle.d.ts +64 -0
- package/dist/chalk/circle.js +193 -0
- package/dist/chalk/clock.d.ts +84 -0
- package/dist/chalk/clock.js +84 -0
- package/dist/chalk/geometry.d.ts +44 -0
- package/dist/chalk/geometry.js +139 -0
- package/dist/chalk/glyphs/capitals.d.ts +12 -0
- package/dist/chalk/glyphs/capitals.js +264 -0
- package/dist/chalk/glyphs/index.d.ts +21 -0
- package/dist/chalk/glyphs/index.js +18 -0
- package/dist/chalk/glyphs/letters.d.ts +13 -0
- package/dist/chalk/glyphs/letters.js +280 -0
- package/dist/chalk/glyphs/metrics.d.ts +33 -0
- package/dist/chalk/glyphs/metrics.js +28 -0
- package/dist/chalk/glyphs/registry.d.ts +7 -0
- package/dist/chalk/glyphs/registry.js +8 -0
- package/dist/chalk/glyphs/sample.d.ts +32 -0
- package/dist/chalk/glyphs/sample.js +102 -0
- package/dist/chalk/glyphs/skeleton.d.ts +64 -0
- package/dist/chalk/glyphs/skeleton.js +126 -0
- package/dist/chalk/glyphs/types.d.ts +58 -0
- package/dist/chalk/glyphs/types.js +17 -0
- package/dist/chalk/index.d.ts +23 -0
- package/dist/chalk/index.js +15 -0
- package/dist/chalk/manifest.d.ts +41 -0
- package/dist/chalk/manifest.js +6 -0
- package/dist/chalk/paint.d.ts +180 -0
- package/dist/chalk/paint.js +210 -0
- package/dist/chalk/pointer.d.ts +8 -0
- package/dist/chalk/pointer.js +21 -0
- package/dist/chalk/prepare.d.ts +11 -0
- package/dist/chalk/prepare.js +15 -0
- package/dist/chalk/scene-schema.d.ts +199 -0
- package/dist/chalk/scene-schema.js +91 -0
- package/dist/chalk/seed.d.ts +3 -0
- package/dist/chalk/seed.js +10 -0
- package/dist/chalk/text-metrics.d.ts +8 -0
- package/dist/chalk/text-metrics.js +156 -0
- package/dist/chalk/timeline.d.ts +47 -0
- package/dist/chalk/timeline.js +84 -0
- package/dist/chalk/types.d.ts +150 -0
- package/dist/chalk/types.js +8 -0
- package/dist/lib/index.d.ts +14 -12
- package/dist/lib/index.js +14 -12
- package/dist/media/draw.d.ts +23 -0
- package/dist/media/draw.js +44 -0
- package/dist/media/mp3.d.ts +6 -0
- package/dist/media/mp3.js +58 -0
- package/dist/media/mp4.d.ts +1 -0
- package/dist/media/mp4.js +58 -0
- package/dist/media/tts-voices.d.ts +18 -0
- package/dist/media/tts-voices.js +606 -0
- package/dist/media/tts.d.ts +56 -0
- package/dist/media/tts.js +174 -0
- package/dist/media/vision.d.ts +25 -0
- package/dist/media/vision.js +71 -0
- package/dist/memory/commit.d.ts +67 -0
- package/dist/memory/commit.js +130 -0
- package/dist/memory/context.d.ts +86 -0
- package/dist/memory/context.js +97 -0
- package/dist/memory/diary.d.ts +84 -0
- package/dist/memory/diary.js +183 -0
- package/dist/memory/grade.d.ts +2 -0
- package/dist/memory/grade.js +7 -0
- package/dist/{lib → memory}/plan.d.ts +1 -1
- package/dist/{lib → memory}/plan.js +1 -1
- package/dist/memory/proposals.d.ts +11 -0
- package/dist/memory/proposals.js +43 -0
- package/dist/memory/retrieval.d.ts +44 -0
- package/dist/memory/retrieval.js +157 -0
- package/dist/{lib → memory}/timetable.d.ts +0 -3
- package/dist/{lib → memory}/timetable.js +0 -11
- package/dist/memory/vault-notes.d.ts +165 -0
- package/dist/memory/vault-notes.js +359 -0
- package/dist/memory/vault.d.ts +70 -0
- package/dist/memory/vault.js +169 -0
- package/dist/realtime/bailian.d.ts +120 -0
- package/dist/realtime/bailian.js +289 -0
- package/dist/realtime/cues.d.ts +51 -0
- package/dist/realtime/cues.js +94 -0
- package/dist/realtime/listen.d.ts +32 -0
- package/dist/realtime/listen.js +53 -0
- package/dist/realtime/preview.d.ts +23 -0
- package/dist/realtime/preview.js +38 -0
- package/dist/realtime/prompt.d.ts +8 -0
- package/dist/realtime/prompt.js +13 -0
- package/dist/realtime/voices.d.ts +21 -0
- package/dist/realtime/voices.js +71 -0
- package/dist/runtime/activities.d.ts +29 -0
- package/dist/runtime/activities.js +72 -0
- package/dist/runtime/activity-state.d.ts +22 -0
- package/dist/runtime/activity-state.js +83 -0
- package/dist/runtime/activity.d.ts +63 -0
- package/dist/runtime/activity.js +428 -0
- package/dist/runtime/agent-file.d.ts +24 -0
- package/dist/runtime/agent-file.js +59 -0
- package/dist/runtime/auto-bookkeep.d.ts +30 -0
- package/dist/runtime/auto-bookkeep.js +84 -0
- package/dist/{lib → runtime/context}/context-pack.d.ts +3 -3
- package/dist/runtime/context/context-pack.js +182 -0
- package/dist/runtime/context/thread-digest.d.ts +4 -0
- package/dist/runtime/context/thread-digest.js +35 -0
- package/dist/runtime/context/tutor-rules.d.ts +25 -0
- package/dist/runtime/context/tutor-rules.js +47 -0
- package/dist/runtime/delivery/delivery.d.ts +94 -0
- package/dist/runtime/delivery/delivery.js +145 -0
- package/dist/runtime/delivery/playback.d.ts +25 -0
- package/dist/runtime/delivery/playback.js +29 -0
- package/dist/runtime/delivery/player.d.ts +145 -0
- package/dist/runtime/delivery/player.js +221 -0
- package/dist/runtime/delivery/queue.d.ts +89 -0
- package/dist/runtime/delivery/queue.js +59 -0
- package/dist/runtime/home/edit.d.ts +39 -0
- package/dist/runtime/home/edit.js +132 -0
- package/dist/runtime/home/home.d.ts +191 -0
- package/dist/runtime/home/home.js +318 -0
- package/dist/runtime/home/store.d.ts +142 -0
- package/dist/runtime/home/store.js +455 -0
- package/dist/runtime/journal/conversation.d.ts +46 -0
- package/dist/runtime/journal/conversation.js +89 -0
- package/dist/runtime/journal/events.d.ts +27 -0
- package/dist/runtime/journal/events.js +136 -0
- package/dist/runtime/journal/kid-log.d.ts +105 -0
- package/dist/runtime/journal/kid-log.js +133 -0
- package/dist/runtime/journal/ledger.d.ts +17 -0
- package/dist/{lib → runtime/journal}/ledger.js +7 -40
- package/dist/runtime/journal/mix.d.ts +42 -0
- package/dist/runtime/journal/mix.js +129 -0
- package/dist/runtime/journal/mouth-index.d.ts +26 -0
- package/dist/runtime/journal/mouth-index.js +34 -0
- package/dist/runtime/journal/mouth.d.ts +54 -0
- package/dist/runtime/journal/mouth.js +102 -0
- package/dist/runtime/journal/recorder.d.ts +91 -0
- package/dist/runtime/journal/recorder.js +148 -0
- package/dist/runtime/journal/store.d.ts +123 -0
- package/dist/runtime/journal/store.js +316 -0
- package/dist/runtime/kid-input.d.ts +16 -0
- package/dist/runtime/kid-input.js +194 -0
- package/dist/runtime/kid-view.d.ts +124 -0
- package/dist/runtime/kid-view.js +157 -0
- package/dist/runtime/lecture.d.ts +86 -0
- package/dist/runtime/lecture.js +237 -0
- package/dist/runtime/live/call.d.ts +231 -0
- package/dist/runtime/live/call.js +1244 -0
- package/dist/runtime/live/turns.d.ts +48 -0
- package/dist/runtime/live/turns.js +102 -0
- package/dist/runtime/runner.d.ts +243 -0
- package/dist/runtime/runner.js +777 -0
- package/dist/runtime/talk-run.d.ts +21 -0
- package/dist/runtime/talk-run.js +34 -0
- package/dist/scenes/dictation/match.d.ts +57 -0
- package/dist/scenes/dictation/match.js +255 -0
- package/dist/scenes/dictation/recognize.d.ts +86 -0
- package/dist/scenes/dictation/recognize.js +163 -0
- package/dist/scenes/dictation/store.d.ts +112 -0
- package/dist/scenes/dictation/store.js +99 -0
- package/dist/scenes/look.d.ts +26 -0
- package/dist/scenes/look.js +1 -0
- package/dist/scenes/paint/painter.d.ts +84 -0
- package/dist/scenes/paint/painter.js +171 -0
- package/dist/scenes/paint/prompt.d.ts +23 -0
- package/dist/scenes/paint/prompt.js +36 -0
- package/dist/scenes/talk/en-words.d.ts +8 -0
- package/dist/scenes/talk/en-words.js +44 -0
- package/dist/scenes/talk/list.d.ts +44 -0
- package/dist/scenes/talk/list.js +88 -0
- package/dist/scenes/talk/store.d.ts +27 -0
- package/dist/scenes/talk/store.js +61 -0
- package/dist/scenes/talk/warmup.d.ts +16 -0
- package/dist/scenes/talk/warmup.js +39 -0
- package/dist/schema/activity.d.ts +149 -0
- package/dist/schema/activity.js +113 -0
- package/dist/schema/board.d.ts +143 -2
- package/dist/schema/board.js +15 -3
- package/dist/schema/config.d.ts +339 -103
- package/dist/schema/config.js +269 -84
- package/dist/schema/context-pack.d.ts +76 -14
- package/dist/schema/context-pack.js +91 -10
- package/dist/{lib/conversation.d.ts → schema/conversation-files.d.ts} +11 -33
- package/dist/schema/conversation-files.js +26 -0
- package/dist/schema/conversation.d.ts +391 -49
- package/dist/schema/conversation.js +135 -19
- package/dist/schema/events.d.ts +138 -0
- package/dist/schema/events.js +1 -0
- package/dist/schema/home.d.ts +56 -0
- package/dist/schema/home.js +35 -0
- package/dist/schema/index.d.ts +14 -3
- package/dist/schema/index.js +14 -3
- package/dist/schema/kid-device.d.ts +20 -0
- package/dist/schema/kid-device.js +32 -0
- package/dist/schema/ledger.d.ts +8 -63
- package/dist/schema/ledger.js +7 -31
- package/dist/schema/memory.d.ts +73 -0
- package/dist/schema/memory.js +47 -0
- package/dist/schema/plan.d.ts +2 -2
- package/dist/schema/plan.js +2 -2
- package/dist/schema/sections.d.ts +32 -25
- package/dist/schema/sections.js +21 -22
- package/dist/schema/theme.d.ts +25 -0
- package/dist/schema/theme.js +26 -0
- package/dist/schema/timetable.d.ts +2 -2
- package/dist/schema/timetable.js +2 -2
- package/dist/schema/workspace.d.ts +68 -0
- package/dist/schema/workspace.js +37 -0
- package/dist/shared/default-port.d.ts +2 -0
- package/dist/shared/default-port.js +2 -0
- package/dist/shared/errors.d.ts +8 -0
- package/dist/shared/errors.js +13 -0
- package/dist/shared/home.d.ts +2 -0
- package/dist/shared/home.js +16 -0
- package/dist/shared/human-notes.d.ts +5 -0
- package/dist/shared/human-notes.js +7 -0
- package/dist/shared/qianwen.d.ts +54 -0
- package/dist/shared/qianwen.js +113 -0
- package/dist/shared/site-url.d.ts +2 -0
- package/dist/shared/site-url.js +5 -0
- package/dist/shared/time.d.ts +9 -0
- package/dist/shared/time.js +22 -0
- package/dist/shared/tokens.d.ts +18 -0
- package/dist/shared/tokens.js +11 -0
- package/dist/shared/wav.d.ts +10 -0
- package/dist/shared/wav.js +50 -0
- package/dist/stage/chunk-226TNLQA.js +129 -0
- package/dist/stage/chunk-24LGQEKE.js +1 -0
- package/dist/stage/chunk-25XV6UY3.js +10 -0
- package/dist/stage/chunk-2AZI3NHJ.js +1 -0
- package/dist/stage/chunk-2BQZTTBE.js +1 -0
- package/dist/stage/chunk-2M7CGY3Y.js +11 -0
- package/dist/stage/chunk-2VR4WFQ7.js +10 -0
- package/dist/stage/chunk-2ZYXBUWG.js +9 -0
- package/dist/stage/chunk-32LAWMGY.js +1 -0
- package/dist/stage/chunk-3LEMTSOO.js +11 -0
- package/dist/stage/chunk-3QCKGZYE.js +32 -0
- package/dist/stage/chunk-44P66WFA.js +1 -0
- package/dist/stage/chunk-4AM6FRR6.js +7 -0
- package/dist/stage/chunk-4QDE4SUK.js +1 -0
- package/dist/stage/chunk-4QESHV3U.js +1 -0
- package/dist/stage/chunk-4SG5QPHB.js +2 -0
- package/dist/stage/chunk-4T4UVCOC.js +1 -0
- package/dist/stage/chunk-4WUEPPG3.js +34 -0
- package/dist/stage/chunk-4YCN6UZ5.js +99 -0
- package/dist/stage/chunk-5V7ZY2AP.js +1 -0
- package/dist/stage/chunk-5VS5Y2VJ.js +6 -0
- package/dist/stage/chunk-5W4NO2ZD.js +62 -0
- package/dist/stage/chunk-65CRNICM.js +1 -0
- package/dist/stage/chunk-66MULO7F.js +5 -0
- package/dist/stage/chunk-6COFQTBS.js +162 -0
- package/dist/stage/chunk-6VZG3M3I.js +8 -0
- package/dist/stage/chunk-7HVDH43T.js +1 -0
- package/dist/stage/chunk-7JLJN4EZ.js +8 -0
- package/dist/stage/chunk-7QDSP4LN.js +1 -0
- package/dist/stage/chunk-7R6OQAO3.js +1 -0
- package/dist/stage/chunk-7VTTHZKW.js +7 -0
- package/dist/stage/chunk-ATHR5KEN.js +10 -0
- package/dist/stage/chunk-B6R5LTP2.js +36 -0
- package/dist/stage/chunk-BD4WE264.js +1 -0
- package/dist/stage/chunk-BONANU47.js +206 -0
- package/dist/stage/chunk-BTVW7OFK.js +89 -0
- package/dist/stage/chunk-BUTJIDHG.js +8 -0
- package/dist/stage/chunk-C2IPYMML.js +84 -0
- package/dist/stage/chunk-C54FTPPV.js +9 -0
- package/dist/stage/chunk-C6LOUF2Z.js +90 -0
- package/dist/stage/chunk-CFF3PILO.js +339 -0
- package/dist/stage/chunk-CI2FQ2JY.js +9 -0
- package/dist/stage/chunk-CW5O4RV7.js +12 -0
- package/dist/stage/chunk-CYABNQYD.js +1 -0
- package/dist/stage/chunk-D7FFA4NS.js +15 -0
- package/dist/stage/chunk-DUNNXU6Z.js +8 -0
- package/dist/stage/chunk-E3E4Q6JF.js +6 -0
- package/dist/stage/chunk-EB3U3LH7.js +9 -0
- package/dist/stage/chunk-EGSZ736B.js +8 -0
- package/dist/stage/chunk-EOBXW5VQ.js +2 -0
- package/dist/stage/chunk-ERZC3B7Y.js +11 -0
- package/dist/stage/chunk-ESDOOBIH.js +11 -0
- package/dist/stage/chunk-EVU4QAL4.js +178 -0
- package/dist/stage/chunk-EVVZI2NY.js +39 -0
- package/dist/stage/chunk-FBKAZUKD.js +39 -0
- package/dist/stage/chunk-FDVKYQJN.js +1 -0
- package/dist/stage/chunk-FGPVYHVR.js +5 -0
- package/dist/stage/chunk-FHUD4AZC.js +1 -0
- package/dist/stage/chunk-FKUJ2DMY.js +96 -0
- package/dist/stage/chunk-FNZGVIJV.js +1 -0
- package/dist/stage/chunk-GBYSEGYM.js +78 -0
- package/dist/stage/chunk-GCO4TDHX.js +1 -0
- package/dist/stage/chunk-GKTML2LG.js +10 -0
- package/dist/stage/chunk-GMDIHHXQ.js +11 -0
- package/dist/stage/chunk-GOUNACI3.js +10 -0
- package/dist/stage/chunk-GXAYATPF.js +3 -0
- package/dist/stage/chunk-H2K2DDXV.js +8 -0
- package/dist/stage/chunk-H3UJI6ZY.js +13 -0
- package/dist/stage/chunk-H6PUGCME.js +7 -0
- package/dist/stage/chunk-HNBUIMIG.js +1 -0
- package/dist/stage/chunk-HRZY2BJQ.js +10 -0
- package/dist/stage/chunk-HSPJGALW.js +30 -0
- package/dist/stage/chunk-IBYORHIP.js +25 -0
- package/dist/stage/chunk-IHF4EWTY.js +1 -0
- package/dist/stage/chunk-ISBRPNKI.js +1 -0
- package/dist/stage/chunk-IZ3OI3C2.js +2 -0
- package/dist/stage/chunk-JEFZAC2R.js +1 -0
- package/dist/stage/chunk-JFIGRDPO.js +1 -0
- package/dist/stage/chunk-JFVYBOOC.js +9 -0
- package/dist/stage/chunk-JGD4TUTQ.js +1 -0
- package/dist/stage/chunk-JO4BEHDH.js +4 -0
- package/dist/stage/chunk-JOWBS42C.js +1 -0
- package/dist/stage/chunk-JP3TM2TG.js +1 -0
- package/dist/stage/chunk-JVK2C52O.js +1 -0
- package/dist/stage/chunk-K4I76XBX.js +14 -0
- package/dist/stage/chunk-KA6CZZ4M.js +1 -0
- package/dist/stage/chunk-KESSJ36M.js +1 -0
- package/dist/stage/chunk-LKATEVRU.js +1 -0
- package/dist/stage/chunk-LS4EJ2EI.js +1 -0
- package/dist/stage/chunk-LUKJQC2X.js +70 -0
- package/dist/stage/chunk-LWULR3SM.js +1 -0
- package/dist/stage/chunk-LWVRFMKX.js +2 -0
- package/dist/stage/chunk-LXC4ZBPZ.js +1 -0
- package/dist/stage/chunk-M2UP255H.js +1 -0
- package/dist/stage/chunk-MAPPXUZQ.js +231 -0
- package/dist/stage/chunk-MBMPW7Z5.js +1 -0
- package/dist/stage/chunk-MD3HMMTK.js +1 -0
- package/dist/stage/chunk-MLPCUIKR.js +17 -0
- package/dist/stage/chunk-MNQIRPDQ.js +8 -0
- package/dist/stage/chunk-MRG7MJVS.js +1 -0
- package/dist/stage/chunk-MU6EXW72.js +10 -0
- package/dist/stage/chunk-MVU2X6LU.js +4 -0
- package/dist/stage/chunk-N6UA5CZV.js +36 -0
- package/dist/stage/chunk-NLZIT2TJ.js +7 -0
- package/dist/stage/chunk-NOJR3J7M.js +1 -0
- package/dist/stage/chunk-NT7ARDOL.js +1 -0
- package/dist/stage/chunk-NWOGMPZH.js +1 -0
- package/dist/stage/chunk-NXE4KMG3.js +40 -0
- package/dist/stage/chunk-O4YCZXD2.js +257 -0
- package/dist/stage/chunk-OAJZ7HLK.js +1 -0
- package/dist/stage/chunk-OCFCFASO.js +1 -0
- package/dist/stage/chunk-ODGPG5RY.js +7 -0
- package/dist/stage/chunk-ODUEA52Q.js +3 -0
- package/dist/stage/chunk-OGDJ3FCI.js +1 -0
- package/dist/stage/chunk-OLDJ55TT.js +1 -0
- package/dist/stage/chunk-OOCL4ATI.js +2 -0
- package/dist/stage/chunk-OQEFDUDV.js +1 -0
- package/dist/stage/chunk-OQWVEWG7.js +4 -0
- package/dist/stage/chunk-OUIX6BGK.js +1 -0
- package/dist/stage/chunk-OV7OZYUO.js +7 -0
- package/dist/stage/chunk-PFGDY33O.js +1 -0
- package/dist/stage/chunk-PFJDUJB3.js +139 -0
- package/dist/stage/chunk-PGEW76ER.js +1 -0
- package/dist/stage/chunk-PP76TAQX.js +32 -0
- package/dist/stage/chunk-PTBOP4OT.js +2 -0
- package/dist/stage/chunk-PX2RVHCK.js +1 -0
- package/dist/stage/chunk-Q7K3PNAD.js +1 -0
- package/dist/stage/chunk-QDDPLZDB.js +1 -0
- package/dist/stage/chunk-QLGLZ77F.js +1 -0
- package/dist/stage/chunk-QOPFDFHI.js +1 -0
- package/dist/stage/chunk-QXT4KAEJ.js +1 -0
- package/dist/stage/chunk-R4YVZCIT.js +1 -0
- package/dist/stage/chunk-R6P6EHWA.js +62 -0
- package/dist/stage/chunk-RCH3OXBI.js +9 -0
- package/dist/stage/chunk-RHPE44I2.js +1 -0
- package/dist/stage/chunk-RJ2R4FVC.js +1 -0
- package/dist/stage/chunk-RJH2YVTD.js +1 -0
- package/dist/stage/chunk-RLWWW5OB.js +6 -0
- package/dist/stage/chunk-S3WO35Z7.js +120 -0
- package/dist/stage/chunk-S7ZGX6MW.js +1 -0
- package/dist/stage/chunk-SIAWX27B.js +1 -0
- package/dist/stage/chunk-SLG4X622.js +1 -0
- package/dist/stage/chunk-SLJRBC77.js +168 -0
- package/dist/stage/chunk-SRORWQJZ.js +1 -0
- package/dist/stage/chunk-STZTUIIF.js +2 -0
- package/dist/stage/chunk-SVQ6MWNV.js +9 -0
- package/dist/stage/chunk-TL3HLL2S.js +132 -0
- package/dist/stage/chunk-U3DOE6SF.js +24 -0
- package/dist/stage/chunk-UABQIZKW.js +6 -0
- package/dist/stage/chunk-UDK3R764.js +1 -0
- package/dist/stage/chunk-UFF4E54B.js +41 -0
- package/dist/stage/chunk-UFP5Q4AY.js +1 -0
- package/dist/stage/chunk-UMH2TSW2.js +72 -0
- package/dist/stage/chunk-UTASVNF5.js +10 -0
- package/dist/stage/chunk-UW7ML5ML.js +88 -0
- package/dist/stage/chunk-V3J7F6OP.js +1 -0
- package/dist/stage/chunk-VEHP5B5Q.js +5 -0
- package/dist/stage/chunk-VRXWB733.js +9 -0
- package/dist/stage/chunk-VVDHBBS5.js +5 -0
- package/dist/stage/chunk-VYFOH6FU.js +106 -0
- package/dist/stage/chunk-W3VZTLQS.js +3 -0
- package/dist/stage/chunk-W7WNRWTZ.js +8 -0
- package/dist/stage/chunk-WHUCV53C.js +1 -0
- package/dist/stage/chunk-WULMYHIF.js +1 -0
- package/dist/stage/chunk-X54EX7AW.js +9 -0
- package/dist/stage/chunk-X565ISZM.js +1 -0
- package/dist/stage/chunk-XGZMDECB.js +1 -0
- package/dist/stage/chunk-XHONC4RF.js +172 -0
- package/dist/stage/chunk-XIK4XQ6E.js +24 -0
- package/dist/stage/chunk-XJQQWFTE.js +1 -0
- package/dist/stage/chunk-XM4WOU3I.js +13 -0
- package/dist/stage/chunk-XM7Y5HP5.js +38 -0
- package/dist/stage/chunk-XNYYRGD5.js +292 -0
- package/dist/stage/chunk-XOYVR3SV.js +1 -0
- package/dist/stage/chunk-XQIW5HCE.js +1 -0
- package/dist/stage/chunk-YEWL7FUW.js +8 -0
- package/dist/stage/chunk-YI55PY3V.js +1 -0
- package/dist/stage/chunk-YM63HI6W.js +1 -0
- package/dist/stage/chunk-YNLGLU4P.js +9 -0
- package/dist/stage/chunk-YTNMNOWP.js +1 -0
- package/dist/stage/chunk-YV62XKTC.js +1 -0
- package/dist/stage/chunk-YVBA3QW6.js +1 -0
- package/dist/stage/chunk-Z2SY2HOC.js +1 -0
- package/dist/stage/chunk-ZBTCQEBK.js +10 -0
- package/dist/stage/chunk-ZCUFN74D.js +1 -0
- package/dist/stage/chunk-ZHOULXEJ.js +11 -0
- package/dist/stage/chunk-ZTRZIET2.js +1 -0
- package/dist/stage/index.html +1 -0
- package/dist/stage/stage.css +1 -1
- package/dist/stage/stage.js +1 -4383
- package/dist/ui/dev/dev-page.d.ts +1 -0
- package/dist/ui/dev/dev-page.js +2021 -0
- package/dist/ui/dev/dev-theme.d.ts +6 -0
- package/dist/ui/dev/dev-theme.js +67 -0
- package/dist/ui/dev/voice-gallery-page.d.ts +1 -0
- package/dist/ui/dev/voice-gallery-page.js +121 -0
- package/dist/ui/dev/voice-scenes.d.ts +21 -0
- package/dist/ui/dev/voice-scenes.js +30 -0
- package/dist/ui/dictation/en-box.d.ts +2 -0
- package/dist/ui/dictation/en-box.js +86 -0
- package/dist/ui/dictation/en-page.d.ts +1 -0
- package/dist/ui/dictation/en-page.js +484 -0
- package/dist/ui/dictation/page.d.ts +1 -0
- package/dist/ui/dictation/page.js +1084 -0
- package/dist/ui/dictation/parent-page.d.ts +1 -0
- package/dist/ui/dictation/parent-page.js +234 -0
- package/dist/ui/dictation/reel-mode.d.ts +1 -0
- package/dist/ui/dictation/reel-mode.js +87 -0
- package/dist/ui/dictation/reel-page.d.ts +1 -0
- package/dist/ui/dictation/reel-page.js +62 -0
- package/dist/ui/dictation/reel.d.ts +163 -0
- package/dist/ui/dictation/reel.js +436 -0
- package/dist/ui/dictation/ui.d.ts +44 -0
- package/dist/ui/dictation/ui.js +80 -0
- package/dist/ui/dictation/unlock.d.ts +7 -0
- package/dist/ui/dictation/unlock.js +16 -0
- package/dist/ui/kid/audio-client.d.ts +11 -0
- package/dist/ui/kid/audio-client.js +74 -0
- package/dist/ui/kid/board-mark-art.d.ts +37 -0
- package/dist/ui/kid/board-mark-art.js +5 -0
- package/dist/ui/kid/board-mark.d.ts +24 -0
- package/dist/ui/kid/board-mark.js +58 -0
- package/dist/ui/kid/home-tiles.d.ts +14 -0
- package/dist/ui/kid/home-tiles.js +44 -0
- package/dist/ui/kid/kid-log.d.ts +15 -0
- package/dist/ui/kid/kid-log.js +87 -0
- package/dist/ui/kid/kid-nav.d.ts +11 -0
- package/dist/ui/kid/kid-nav.js +22 -0
- package/dist/ui/kid/kid-page.d.ts +9 -0
- package/dist/ui/kid/kid-page.js +3684 -0
- package/dist/ui/kid/letters.d.ts +26 -0
- package/dist/ui/kid/letters.js +51 -0
- package/dist/ui/kid/photo-edit.d.ts +83 -0
- package/dist/ui/kid/photo-edit.js +106 -0
- package/dist/ui/kid/photo-ui.d.ts +23 -0
- package/dist/ui/kid/photo-ui.js +60 -0
- package/dist/ui/kid/reel.d.ts +419 -0
- package/dist/ui/kid/reel.js +648 -0
- package/dist/ui/kid/tianzige.d.ts +8 -0
- package/dist/ui/kid/tianzige.js +45 -0
- package/dist/ui/kid/tutor-face.d.ts +35 -0
- package/dist/ui/kid/tutor-face.js +84 -0
- package/dist/ui/kid/voice-ui.d.ts +70 -0
- package/dist/ui/kid/voice-ui.js +316 -0
- package/dist/ui/kid/voice-view.d.ts +71 -0
- package/dist/ui/kid/voice-view.js +75 -0
- package/dist/ui/kid/word-draw.d.ts +2 -0
- package/dist/ui/kid/word-draw.js +107 -0
- package/dist/ui/kid/word-emoji.d.ts +10 -0
- package/dist/ui/kid/word-emoji.js +68 -0
- package/dist/ui/kid/word-layout.d.ts +25 -0
- package/dist/ui/kid/word-layout.js +29 -0
- package/dist/ui/parent/parent-home-page.d.ts +1 -0
- package/dist/ui/parent/parent-home-page.js +722 -0
- package/dist/ui/parent/parent-page.d.ts +2 -0
- package/dist/ui/parent/parent-page.js +511 -0
- package/dist/ui/parent/parent-settings-page.d.ts +1 -0
- package/dist/ui/parent/parent-settings-page.js +133 -0
- package/dist/ui/parent/qr-page.d.ts +8 -0
- package/dist/ui/parent/qr-page.js +66 -0
- package/dist/ui/shared/brand.d.ts +38 -0
- package/dist/ui/shared/brand.js +53 -0
- package/dist/ui/shared/favicon.d.ts +12 -0
- package/dist/ui/shared/favicon.js +96 -0
- package/dist/ui/shared/icon.d.ts +9 -0
- package/dist/ui/shared/icon.js +35 -0
- package/dist/ui/shared/inline-lib.d.ts +1 -0
- package/dist/ui/shared/inline-lib.js +28 -0
- package/dist/ui/shared/logo.d.ts +31 -0
- package/dist/ui/shared/logo.js +43 -0
- package/dist/ui/shared/page-dom.d.ts +12 -0
- package/dist/ui/shared/page-dom.js +36 -0
- package/dist/ui/shared/png.d.ts +1 -0
- package/dist/ui/shared/png.js +45 -0
- package/dist/ui/shared/qr-svg.d.ts +3 -0
- package/dist/ui/shared/qr-svg.js +32 -0
- package/dist/ui/shared/qr.d.ts +14 -0
- package/dist/ui/shared/qr.js +281 -0
- package/dist/ui/shared/reel-dock.d.ts +22 -0
- package/dist/ui/shared/reel-dock.js +365 -0
- package/dist/ui/shared/tutor-color.d.ts +15 -0
- package/dist/ui/shared/tutor-color.js +47 -0
- package/dist/ui/talk/page.d.ts +6 -0
- package/dist/ui/talk/page.js +294 -0
- package/grades/grade-2/README.md +11 -0
- package/grades/grade-2/VALIDATION.md +41 -0
- package/grades/grade-2/agents/chinese-tutor/activities//344/275/240/350/257/264/346/210/221/347/224/273.md +157 -0
- 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
- 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
- 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
- package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235.md +64 -0
- package/grades/grade-2/agents/chinese-tutor/activities//345/206/231/350/257/235./344/276/213/345/255/220.md +31 -0
- package/grades/grade-2/agents/chinese-tutor/activities//345/220/254/345/206/231.md +48 -0
- package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240.md +79 -0
- package/grades/grade-2/agents/chinese-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/chinese-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
- package/grades/grade-2/agents/chinese-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +81 -0
- 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
- package/grades/grade-2/agents/chinese-tutor/activities//347/234/213/345/233/276/350/257/264/350/257/235.md +94 -0
- 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
- package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240.md +82 -0
- package/grades/grade-2/agents/chinese-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/chinese-tutor.md +59 -0
- package/grades/grade-2/agents/english-tutor/activities//345/217/243/350/257/255/350/257/276.md +149 -0
- 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
- package/grades/grade-2/agents/english-tutor/activities//345/220/254/345/206/231.md +47 -0
- package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240.md +78 -0
- package/grades/grade-2/agents/english-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/english-tutor/activities//345/260/217/350/257/276/345/240/202.md +53 -0
- package/grades/grade-2/agents/english-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +80 -0
- 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
- package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240.md +86 -0
- package/grades/grade-2/agents/english-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/english-tutor.md +57 -0
- package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240.md +78 -0
- package/grades/grade-2/agents/math-tutor/activities//345/244/215/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/math-tutor/activities//345/260/217/350/257/276/345/240/202.md +56 -0
- 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
- package/grades/grade-2/agents/math-tutor/activities//346/243/200/346/237/245/344/275/234/344/270/232.md +80 -0
- 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
- package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240.md +81 -0
- package/grades/grade-2/agents/math-tutor/activities//351/242/204/344/271/240./344/276/213/345/255/220.md +35 -0
- package/grades/grade-2/agents/math-tutor.md +51 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/index.json +44 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-1.mp3 +0 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-2.mp3 +0 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-3.mp3 +0 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-4.mp3 +0 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/audio/step-5.mp3 +0 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/bake.json +1 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/manifest.json +63 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen/scene.json +247 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen.md +40 -0
- package/grades/grade-2/examples/2026-10-27-pingjunfen.ts +26 -0
- package/grades/grade-2/examples//345/271/263/345/235/207/345/210/206./344/276/213/345/255/220.md +24 -0
- package/grades/grade-2/examples//346/225/260/345/255/246/345/271/263/345/235/207/345/210/206.md +42 -0
- package/grades/grade-2/validation/2026-10-27.json +4410 -0
- package/package.json +27 -15
- package/skills/chalk-cli/SKILL.md +62 -0
- package/skills/chalk-scene/SKILL.md +91 -0
- package/skills/chalk-teaching/SKILL.md +82 -0
- 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
- package/skills/chalk-teaching/models//345/207/221/345/215/201.md +7 -0
- package/skills/chalk-teaching/models//345/221/250/346/234/237/350/247/204/345/276/213.md +6 -0
- package/skills/chalk-teaching/models//345/256/236/347/211/251/345/233/276-/345/242/236/345/207/217.md +6 -0
- 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
- 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
- package/skills/chalk-teaching/models//345/260/217/346/243/222/350/277/233/344/275/215/345/212/240.md +7 -0
- package/skills/chalk-teaching/models//345/260/217/346/243/222/351/200/200/344/275/215/345/207/217.md +6 -0
- package/skills/chalk-teaching/models//346/216/222/351/230/237/347/202/271/351/230/265.md +7 -0
- package/skills/chalk-teaching/models//346/227/266/351/227/264/346/225/260/350/275/264.md +6 -0
- package/skills/chalk-teaching/models//346/245/274/345/261/202/351/227/264/351/232/224/345/233/276.md +7 -0
- package/skills/chalk-teaching/models//347/240/264/345/215/201.md +7 -0
- package/skills/chalk-teaching/models//347/253/226/345/274/217/351/200/200/344/275/215.md +6 -0
- package/skills/chalk-teaching/models//347/272/277/346/256/265/345/233/276.md +7 -0
- package/skills/chalk-teaching/models-index.md +24 -0
- 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
- package/skills/chalk-teaching/references//350/257/264/346/230/216/346/226/207/344/273/266.md +102 -0
- package/skills/chalk-verify/SKILL.md +57 -0
- package/skills/chalk-verify/references//350/257/204/345/210/244/346/240/207/345/207/206.md +69 -0
- package/skills/cotutor-analyze/SKILL.md +106 -0
- package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +31 -0
- package/skills/cotutor-board/SKILL.md +373 -0
- package/skills/cotutor-board/references/README.md +38 -0
- package/skills/cotutor-board/references/canvas.md +68 -0
- package/skills/cotutor-board/references/choice.md +55 -0
- package/skills/cotutor-board/references/code.md +46 -0
- package/skills/cotutor-board/references/image.md +52 -0
- package/skills/cotutor-board/references/lecture.md +69 -0
- package/skills/cotutor-board/references/paint.md +77 -0
- package/skills/cotutor-board/references/photo.md +61 -0
- package/skills/cotutor-board/references/read.md +51 -0
- package/skills/cotutor-board/references/text.md +69 -0
- package/skills/cotutor-board/references/tianzige.md +78 -0
- package/skills/cotutor-board/references/word.md +91 -0
- package/skills/cotutor-home/SKILL.md +170 -0
- package/skills/cotutor-home/references/dictation.md +97 -0
- package/skills/cotutor-home/references/tutor.md +149 -0
- package/skills/cotutor-home/references//345/221/275/344/273/244.md +21 -0
- package/skills/cotutor-home/references//351/246/226/351/241/265/350/257/255/346/263/225.md +143 -0
- package/skills/cotutor-tune/SKILL.md +147 -0
- package/skills/cotutor-tune/references//345/255/227/346/256/265.md +53 -0
- package/skills/cotutor-tutor/SKILL.md +253 -0
- package/skills/cotutor-tutor/references//344/270/212/344/270/213/346/226/207/345/214/205.md +78 -0
- package/themes/default/kid.css +86 -0
- package/themes/default/theme.json +26 -0
- package/agents/chinese-tutor.md +0 -67
- package/agents/homework-tutor.md +0 -17
- package/agents/math-tutor.md +0 -68
- package/agents/planner.md +0 -18
- package/agents/reading-tutor.md +0 -65
- package/agents/scene-maker.md +0 -41
- package/dist/cards/canvas.d.ts +0 -22
- package/dist/cards/canvas.js +0 -65
- package/dist/cards/fill.d.ts +0 -14
- package/dist/cards/fill.js +0 -64
- package/dist/cards/index.d.ts +0 -48
- package/dist/cards/index.js +0 -115
- package/dist/cards/kind.js +0 -7
- package/dist/cards/scene.d.ts +0 -24
- package/dist/cards/scene.js +0 -67
- package/dist/cards/text.d.ts +0 -18
- package/dist/cards/text.js +0 -41
- package/dist/cli/cert.d.ts +0 -7
- package/dist/cli/cert.js +0 -36
- package/dist/cli/doctor.d.ts +0 -22
- package/dist/cli/doctor.js +0 -355
- package/dist/cli/init.js +0 -116
- package/dist/cli/main.js +0 -243
- package/dist/cli/serve.d.ts +0 -30
- package/dist/cli/serve.js +0 -56
- package/dist/cli/skeleton.d.ts +0 -39
- package/dist/cli/skeleton.js +0 -184
- package/dist/cli/skills.d.ts +0 -40
- package/dist/cli/skills.js +0 -170
- package/dist/cli/workspace.d.ts +0 -69
- package/dist/lib/agent-file.d.ts +0 -10
- package/dist/lib/agent-file.js +0 -16
- package/dist/lib/board.d.ts +0 -15
- package/dist/lib/board.js +0 -107
- package/dist/lib/context-pack.js +0 -55
- package/dist/lib/conversation.js +0 -88
- package/dist/lib/kid-board.d.ts +0 -148
- package/dist/lib/kid-board.js +0 -294
- package/dist/lib/kid-view.d.ts +0 -63
- package/dist/lib/kid-view.js +0 -93
- package/dist/lib/ledger.d.ts +0 -29
- package/dist/lib/run-plan.d.ts +0 -30
- package/dist/lib/run-plan.js +0 -32
- package/dist/lib/sections.d.ts +0 -12
- package/dist/lib/sections.js +0 -151
- package/dist/lib/stream.d.ts +0 -15
- package/dist/lib/stream.js +0 -69
- package/dist/lib/transcript.d.ts +0 -36
- package/dist/lib/transcript.js +0 -95
- package/dist/server/app.d.ts +0 -74
- package/dist/server/app.js +0 -406
- package/dist/server/kid-page.d.ts +0 -1
- package/dist/server/kid-page.js +0 -768
- package/dist/server/mock.js +0 -403
- package/dist/server/parent-page.d.ts +0 -8
- package/dist/server/parent-page.js +0 -393
- package/dist/server/runner.d.ts +0 -64
- package/dist/server/runner.js +0 -277
- package/dist/server/scene-props.d.ts +0 -16
- package/dist/server/scene-props.js +0 -39
- package/dist/server/store.d.ts +0 -43
- package/dist/server/store.js +0 -210
- package/dist/server/tts.d.ts +0 -51
- package/dist/server/tts.js +0 -99
- /package/dist/{cli → app/cli}/main.d.ts +0 -0
- /package/dist/{cards → board/cards}/choice.d.ts +0 -0
- /package/dist/{cards → board/cards}/code.d.ts +0 -0
- /package/dist/{cards → board/cards}/image.d.ts +0 -0
- /package/dist/{cards → board/cards}/read.d.ts +0 -0
|
@@ -10,12 +10,9 @@ export interface TimetableParse {
|
|
|
10
10
|
errors: string[];
|
|
11
11
|
found: boolean;
|
|
12
12
|
}
|
|
13
|
-
export declare function dayName(day: number): string;
|
|
14
13
|
export declare function parseTimetable(md: string): TimetableParse;
|
|
15
14
|
/** js Date → 1–7(周一–周日) */
|
|
16
15
|
export declare function dayOf(now: Date): number;
|
|
17
|
-
/** 本周(周一起算)第 day 天的日期 YYYY-MM-DD */
|
|
18
|
-
export declare function weekDate(now: Date, day: number): string;
|
|
19
16
|
/** 当前正在进行的时段(第一条命中;不在任何时段 = null,不猜) */
|
|
20
17
|
export declare function currentSlot(entries: readonly TimetableEntry[], now: Date): TimetableEntry | null;
|
|
21
18
|
/** 上下文包的 slot 字段:「数学 16:00-17:00」 */
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
const REQUIRED = ['星期', '时间', '学科'];
|
|
2
2
|
const DAY_MAP = { 一: 1, 二: 2, 三: 3, 四: 4, 五: 5, 六: 6, 日: 7, 天: 7 };
|
|
3
|
-
const DAY_NAMES = ['', '一', '二', '三', '四', '五', '六', '日'];
|
|
4
|
-
export function dayName(day) {
|
|
5
|
-
return `周${DAY_NAMES[day] ?? '?'}`;
|
|
6
|
-
}
|
|
7
3
|
const cells = (line) => line
|
|
8
4
|
.replace(/^\s*\|/, '')
|
|
9
5
|
.replace(/\|\s*$/, '')
|
|
@@ -87,13 +83,6 @@ export function dayOf(now) {
|
|
|
87
83
|
const d = now.getDay();
|
|
88
84
|
return d === 0 ? 7 : d;
|
|
89
85
|
}
|
|
90
|
-
/** 本周(周一起算)第 day 天的日期 YYYY-MM-DD */
|
|
91
|
-
export function weekDate(now, day) {
|
|
92
|
-
const d = new Date(now);
|
|
93
|
-
d.setDate(d.getDate() + (day - dayOf(now)));
|
|
94
|
-
const p = (n) => String(n).padStart(2, '0');
|
|
95
|
-
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
96
|
-
}
|
|
97
86
|
/** 当前正在进行的时段(第一条命中;不在任何时段 = null,不猜) */
|
|
98
87
|
export function currentSlot(entries, now) {
|
|
99
88
|
const day = dayOf(now);
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vault 里家长写的笔记按 frontmatter 定位(《obsidian仓库设计.md》):
|
|
3
|
+
* `cotutor: profile | subject | textbook`,不认文件名与目录——家长会改名、挪位置。
|
|
4
|
+
* - profile:孩子档案,一个 vault 一个;`school_start: YYYY-MM` 算当前学期,`semester` 可覆盖
|
|
5
|
+
* - subject:一科一学期一个,就是这位老师的**入口文件**,原文整篇进上下文包
|
|
6
|
+
* - textbook:可以没有、可以多本;只给路径,老师要用自己 Read
|
|
7
|
+
* - memory:一个 agent 一篇(`agent: <name>`),老师在回复里写「## 记忆」、应用追加;家长可读可改,原文整篇进上下文包。
|
|
8
|
+
* `agent: all` 那篇是孩子的记忆(2026-10-30):关于孩子本人、换一科也成立的,所有有脸的老师共用,老师写 `孩子:` 开头的行进这里
|
|
9
|
+
* 程序读的键用英文(cotutor / subject / semester / school_start / agent),中文键是给人看的描述,这里不读。
|
|
10
|
+
*/
|
|
11
|
+
import type { MemoryLine } from '../schema/index.ts';
|
|
12
|
+
export declare const NOTE_KINDS: readonly ["profile", "subject", "textbook", "memory"];
|
|
13
|
+
export type NoteKind = (typeof NOTE_KINDS)[number];
|
|
14
|
+
export interface VaultNote {
|
|
15
|
+
/** 相对 vault 根,`/` 分隔 */
|
|
16
|
+
path: string;
|
|
17
|
+
props: Record<string, string>;
|
|
18
|
+
/** 整篇原文(含 frontmatter) */
|
|
19
|
+
text: string;
|
|
20
|
+
}
|
|
21
|
+
/** 只认平铺的 `key: value`;值去掉成对引号。没有 frontmatter → {} */
|
|
22
|
+
export declare function frontmatter(md: string): Record<string, string>;
|
|
23
|
+
/**
|
|
24
|
+
* 某天是几年级的哪个学期 / 假期:9–1 月上学期、2 月寒假、3–6 月下学期、7–8 月暑假(刚读完的那个年级的暑假)。
|
|
25
|
+
* 学年从 9 月算;`school_start` 是读一年级那年的 9 月(写别的月份也按它所在学年算)。年级不在 1–12 → null。
|
|
26
|
+
*/
|
|
27
|
+
export declare function semesterAt(schoolStart: string, date: string): string | null;
|
|
28
|
+
/** 正文里的 `[[目标]]` / `![[目标|别名]]`:去掉 #节 与 |别名,去重,按出现顺序 */
|
|
29
|
+
export declare function wikilinks(md: string): string[];
|
|
30
|
+
/** 像 Obsidian 那样解析链接:先按相对根的完整路径(可省 .md),再按文件名(同名取路径最短的);找不到 → null */
|
|
31
|
+
export declare function resolveLink(target: string, files: readonly string[]): string | null;
|
|
32
|
+
export interface VaultPick {
|
|
33
|
+
profile: VaultNote | null;
|
|
34
|
+
/** 不止一个 `cotutor: profile` 时的其余几个(用写了 school_start / semester 的、再按路径的第一篇,doctor 报) */
|
|
35
|
+
extraProfiles: string[];
|
|
36
|
+
/** 当前学期;档案没有、没写 school_start 也没写 semester、或年级算不出 → null */
|
|
37
|
+
semester: string | null;
|
|
38
|
+
/** 这科这学期的入口文件;没有 → null(不沿用上学期的) */
|
|
39
|
+
entry: VaultNote | null;
|
|
40
|
+
/** 同一科同一学期不止一个入口文件时的其余几个 */
|
|
41
|
+
extraEntries: string[];
|
|
42
|
+
/** 这位 agent 的记忆文件;还没有 → null */
|
|
43
|
+
memory: VaultNote | null;
|
|
44
|
+
extraMemories: string[];
|
|
45
|
+
/** 孩子的记忆(`agent: all`);还没有 → null */
|
|
46
|
+
child: VaultNote | null;
|
|
47
|
+
/** 参考资料的路径:这科这学期的教材 + 档案与入口文件里的 [[链接]](去重,不含它俩自己) */
|
|
48
|
+
refs: string[];
|
|
49
|
+
/** 这科这学期的教材(取材用,memory/retrieval.ts) */
|
|
50
|
+
textbooks: VaultNote[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 从扫出来的笔记里挑一位老师要的:档案、当前学期、入口文件、参考路径。
|
|
54
|
+
* `files` 是 vault 里所有文件的相对路径(解析 [[链接]] 用,不限 .md)。subject 没配 → 没有入口文件。
|
|
55
|
+
*/
|
|
56
|
+
export declare function pickNotes(notes: readonly VaultNote[], files: readonly string[], opts: {
|
|
57
|
+
date: string;
|
|
58
|
+
subject?: string;
|
|
59
|
+
agent?: string;
|
|
60
|
+
}): VaultPick;
|
|
61
|
+
/** 入口文件缺了为什么(进上下文包 entry: 与这条消息的 warnings;家长端就看得到) */
|
|
62
|
+
export declare function missingEntry(subject: string | undefined, pick: {
|
|
63
|
+
profile: unknown;
|
|
64
|
+
semester: string | null;
|
|
65
|
+
}): string;
|
|
66
|
+
/** 记忆文件缺省位置:记忆/<显示名>.md(显示名里的 / 换掉) */
|
|
67
|
+
export declare function memoryPath(display: string): string;
|
|
68
|
+
/** 新建的记忆文件 */
|
|
69
|
+
export declare function memoryTemplate(agent: string, display: string): string;
|
|
70
|
+
/** 孩子的记忆(2026-10-30):`agent: all` 的那篇,缺省在 记忆/孩子.md;满了(列表行到 CHILD_MEMORY_CAP 条)新的不再进,提醒家长删 */
|
|
71
|
+
export declare const CHILD_MEMORY_AGENT = "all";
|
|
72
|
+
export declare const CHILD_MEMORY_PATH = "\u8BB0\u5FC6/\u5B69\u5B50.md";
|
|
73
|
+
export declare const CHILD_MEMORY_CAP = 20;
|
|
74
|
+
/** 新建的孩子的记忆 */
|
|
75
|
+
export declare function childMemoryTemplate(): string;
|
|
76
|
+
/**
|
|
77
|
+
* 往记忆文件末尾追加:每条一行 `- <日期> <原话>`(老师自己写了日期开头就不再加);文里已有同样的话就跳过。
|
|
78
|
+
* cap:列表行最多这么多条,满了的不加,进 full。返回新全文与真加上的行;一条都没加 → text 原样。
|
|
79
|
+
*/
|
|
80
|
+
export declare function appendMemory(existing: string, items: readonly string[], date: string, cap?: number): {
|
|
81
|
+
text: string;
|
|
82
|
+
added: string[];
|
|
83
|
+
full: string[];
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* 「## 记忆」段的一条(2026-09-18):缺省是新增;`改:原话 → 新的` 改一行;`删:原话` 删一行。
|
|
87
|
+
* 冒号全角半角都认,箭头认 → 与 ->。原话或新的里也有箭头(「宇宙→太空员」、骨架「数一数 → 分一分」)时切法不止一种:
|
|
88
|
+
* from / to 是从第一个箭头切的,alt 是其余箭头的切法(从左到右),applyMemoryOps 挑原话对得上的那种(2026-10-31)。
|
|
89
|
+
*/
|
|
90
|
+
export type MemoryOp = {
|
|
91
|
+
op: 'add';
|
|
92
|
+
text: string;
|
|
93
|
+
} | {
|
|
94
|
+
op: 'change';
|
|
95
|
+
from: string;
|
|
96
|
+
to: string;
|
|
97
|
+
alt?: {
|
|
98
|
+
from: string;
|
|
99
|
+
to: string;
|
|
100
|
+
}[];
|
|
101
|
+
} | {
|
|
102
|
+
op: 'delete';
|
|
103
|
+
from: string;
|
|
104
|
+
};
|
|
105
|
+
export declare function parseMemoryOp(item: string): MemoryOp;
|
|
106
|
+
/** 一行改动给家长看的样子:新增的原话、「改:旧 → 新」、「删:旧」(家长端「记录」的「记住了」) */
|
|
107
|
+
export declare function memoryLineText(l: MemoryLine): string;
|
|
108
|
+
/**
|
|
109
|
+
* 按原话找一行:正文(frontmatter 之后)里原话一字不差的那行;没有就找唯一一行包含它的(原话至少 4 个字);都不是 → -1。
|
|
110
|
+
* 不分老师写的、家长写的(2026-09-18 定:机器一律可以改)。fuzzy = false 只认一字不差的(这轮里家长改过文件,2026-10-30)。
|
|
111
|
+
*/
|
|
112
|
+
export declare function findMemoryLine(lines: readonly string[], from: string, bodyStart: number, fuzzy?: boolean): number;
|
|
113
|
+
export interface MemoryApplied {
|
|
114
|
+
text: string;
|
|
115
|
+
/** 给家长看的改动,一条一行:新增的原样(`- <日期> …`),改的「改:旧 → 新」,删的「删:旧」 */
|
|
116
|
+
changes: string[];
|
|
117
|
+
/** 找不到原话的改 / 删 */
|
|
118
|
+
misses: string[];
|
|
119
|
+
/** 满了没加上的新增(有 cap 时) */
|
|
120
|
+
full: string[];
|
|
121
|
+
/** 同一批改动的整行原文:before = 改之前那行(新增为 null),after = 改之后那行(删掉为 null);删话题时 undoMemoryLines 按它撤销 */
|
|
122
|
+
lines: MemoryLine[];
|
|
123
|
+
}
|
|
124
|
+
export type { MemoryLine };
|
|
125
|
+
/**
|
|
126
|
+
* 把一串操作落到记忆全文上:先改、删(按原话找行,见 findMemoryLine),再把新增的追加到末尾(appendMemory,去重)。
|
|
127
|
+
* 改过的列表行换成 `- <今天> 新的`(新的自己带着日期就去掉,不写两个日期);不是列表的行整行换成新的。strict:改、删只认一字不差的原话;cap:新增后最多几条(先删后加,删掉的腾出地方)。
|
|
128
|
+
* 改有几种切法(parseMemoryOp 的 alt)时:先挑原话一字不差的那种;都不是再模糊找,原话长的先(短的是长的前缀,会把原话后半截切进新的里)。
|
|
129
|
+
*/
|
|
130
|
+
export declare function applyMemoryOps(existing: string, ops: readonly MemoryOp[], date: string, opts?: {
|
|
131
|
+
strict?: boolean;
|
|
132
|
+
cap?: number;
|
|
133
|
+
}): MemoryApplied;
|
|
134
|
+
/**
|
|
135
|
+
* 撤销一串改动(删话题时,2026-10-05):倒着来——改了的换回原来那行,新增的删掉,删了的接回末尾(原来的位置不记)。
|
|
136
|
+
* 按整行原文找;家长或整理那轮后来又改过那行就找不到,进 misses,不动。
|
|
137
|
+
*/
|
|
138
|
+
export declare function undoMemoryLines(existing: string, edits: readonly MemoryLine[]): {
|
|
139
|
+
text: string;
|
|
140
|
+
undone: number;
|
|
141
|
+
misses: string[];
|
|
142
|
+
};
|
|
143
|
+
/** 记忆文件里有几条(frontmatter 之后的列表行) */
|
|
144
|
+
export declare function memoryCount(text: string): number;
|
|
145
|
+
/**
|
|
146
|
+
* 记账后整理记忆那轮的消息正文(2026-09-18):新会话、from: system;记忆原文在上下文包的 <vault-note role="memory">。
|
|
147
|
+
* 回的「## 记忆」段不受每轮条数上限,应用照单落盘、不问家长(家长在 Obsidian 里兜底)。
|
|
148
|
+
*/
|
|
149
|
+
export declare function tidyMemoryPrompt(opts: {
|
|
150
|
+
date: string;
|
|
151
|
+
count: number;
|
|
152
|
+
cap: number;
|
|
153
|
+
diaryFile: string;
|
|
154
|
+
}): string;
|
|
155
|
+
/**
|
|
156
|
+
* 按 entryChars 截一篇笔记带进上下文包。档案、入口文件留开头(家长写在前面的最要紧);
|
|
157
|
+
* 记忆留末尾——应用往末尾追加,最新的在后面,截开头丢的是旧的(2026-09-18 之前留的是开头,越记越看不到新的)。
|
|
158
|
+
* 末尾那头从一行的开头起,不截半行。
|
|
159
|
+
*/
|
|
160
|
+
export declare function clipNote(text: string, limit: number, keep: 'head' | 'tail'): {
|
|
161
|
+
text: string;
|
|
162
|
+
cut: boolean;
|
|
163
|
+
};
|
|
164
|
+
/** 短 hash(FNV-1a 32 位):同一话题里判断「这篇上次带过、没改」 */
|
|
165
|
+
export declare function textHash(s: string): string;
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vault 里家长写的笔记按 frontmatter 定位(《obsidian仓库设计.md》):
|
|
3
|
+
* `cotutor: profile | subject | textbook`,不认文件名与目录——家长会改名、挪位置。
|
|
4
|
+
* - profile:孩子档案,一个 vault 一个;`school_start: YYYY-MM` 算当前学期,`semester` 可覆盖
|
|
5
|
+
* - subject:一科一学期一个,就是这位老师的**入口文件**,原文整篇进上下文包
|
|
6
|
+
* - textbook:可以没有、可以多本;只给路径,老师要用自己 Read
|
|
7
|
+
* - memory:一个 agent 一篇(`agent: <name>`),老师在回复里写「## 记忆」、应用追加;家长可读可改,原文整篇进上下文包。
|
|
8
|
+
* `agent: all` 那篇是孩子的记忆(2026-10-30):关于孩子本人、换一科也成立的,所有有脸的老师共用,老师写 `孩子:` 开头的行进这里
|
|
9
|
+
* 程序读的键用英文(cotutor / subject / semester / school_start / agent),中文键是给人看的描述,这里不读。
|
|
10
|
+
*/
|
|
11
|
+
export const NOTE_KINDS = ['profile', 'subject', 'textbook', 'memory'];
|
|
12
|
+
/** 只认平铺的 `key: value`;值去掉成对引号。没有 frontmatter → {} */
|
|
13
|
+
export function frontmatter(md) {
|
|
14
|
+
const lines = md.replace(/^\uFEFF/, '').split(/\r?\n/);
|
|
15
|
+
if (lines[0]?.trim() !== '---')
|
|
16
|
+
return {};
|
|
17
|
+
const out = {};
|
|
18
|
+
for (let i = 1; i < lines.length; i++) {
|
|
19
|
+
const l = lines[i];
|
|
20
|
+
if (l.trim() === '---')
|
|
21
|
+
return out;
|
|
22
|
+
const m = /^([^\s:#][^:]*?)\s*:\s*(.*)$/.exec(l);
|
|
23
|
+
if (!m)
|
|
24
|
+
continue;
|
|
25
|
+
let v = m[2].trim();
|
|
26
|
+
if (v.length >= 2 && ((v[0] === '"' && v.at(-1) === '"') || (v[0] === "'" && v.at(-1) === "'")))
|
|
27
|
+
v = v.slice(1, -1);
|
|
28
|
+
out[m[1]] = v;
|
|
29
|
+
}
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
const CN_DIGITS = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'];
|
|
33
|
+
/**
|
|
34
|
+
* 某天是几年级的哪个学期 / 假期:9–1 月上学期、2 月寒假、3–6 月下学期、7–8 月暑假(刚读完的那个年级的暑假)。
|
|
35
|
+
* 学年从 9 月算;`school_start` 是读一年级那年的 9 月(写别的月份也按它所在学年算)。年级不在 1–12 → null。
|
|
36
|
+
*/
|
|
37
|
+
export function semesterAt(schoolStart, date) {
|
|
38
|
+
const s = /^(\d{4})-(\d{1,2})$/.exec(schoolStart.trim());
|
|
39
|
+
const d = /^(\d{4})-(\d{2})-\d{2}/.exec(date);
|
|
40
|
+
if (!s || !d)
|
|
41
|
+
return null;
|
|
42
|
+
const sm = Number(s[2]);
|
|
43
|
+
if (sm < 1 || sm > 12)
|
|
44
|
+
return null;
|
|
45
|
+
const startYear = sm >= 9 ? Number(s[1]) : Number(s[1]) - 1;
|
|
46
|
+
const y = Number(d[1]);
|
|
47
|
+
const m = Number(d[2]);
|
|
48
|
+
const schoolYear = m >= 9 ? y : y - 1;
|
|
49
|
+
const grade = schoolYear - startYear + 1;
|
|
50
|
+
if (grade < 1 || grade >= CN_DIGITS.length)
|
|
51
|
+
return null;
|
|
52
|
+
const term = m >= 9 || m === 1 ? '上' : m === 2 ? '寒假' : m <= 6 ? '下' : '暑假';
|
|
53
|
+
return `${CN_DIGITS[grade]}年级${term}`;
|
|
54
|
+
}
|
|
55
|
+
/** 正文里的 `[[目标]]` / `![[目标|别名]]`:去掉 #节 与 |别名,去重,按出现顺序 */
|
|
56
|
+
export function wikilinks(md) {
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const m of md.matchAll(/!?\[\[([^\]|#]*)(?:#[^\]|]*)?(?:\|[^\]]*)?\]\]/g)) {
|
|
59
|
+
const t = m[1].trim();
|
|
60
|
+
if (t && !out.includes(t))
|
|
61
|
+
out.push(t);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
/** 像 Obsidian 那样解析链接:先按相对根的完整路径(可省 .md),再按文件名(同名取路径最短的);找不到 → null */
|
|
66
|
+
export function resolveLink(target, files) {
|
|
67
|
+
const t = target.replace(/^\/+/, '');
|
|
68
|
+
const exact = files.find((f) => f === t || f === `${t}.md`);
|
|
69
|
+
if (exact)
|
|
70
|
+
return exact;
|
|
71
|
+
const base = t.includes('/') ? null : t;
|
|
72
|
+
if (!base)
|
|
73
|
+
return null;
|
|
74
|
+
const hits = files.filter((f) => {
|
|
75
|
+
const name = f.slice(f.lastIndexOf('/') + 1);
|
|
76
|
+
return name === base || name === `${base}.md`;
|
|
77
|
+
});
|
|
78
|
+
return hits.sort((a, b) => a.length - b.length || a.localeCompare(b))[0] ?? null;
|
|
79
|
+
}
|
|
80
|
+
const byPath = (a, b) => a.path.localeCompare(b.path);
|
|
81
|
+
/**
|
|
82
|
+
* 从扫出来的笔记里挑一位老师要的:档案、当前学期、入口文件、参考路径。
|
|
83
|
+
* `files` 是 vault 里所有文件的相对路径(解析 [[链接]] 用,不限 .md)。subject 没配 → 没有入口文件。
|
|
84
|
+
*/
|
|
85
|
+
export function pickNotes(notes, files, opts) {
|
|
86
|
+
const of = (k) => notes.filter((n) => n.props.cotutor === k).sort(byPath);
|
|
87
|
+
// 不止一篇时先要写了学期信息的那篇
|
|
88
|
+
const dated = (n) => (n.props.semester?.trim() || n.props.school_start?.trim() ? 0 : 1);
|
|
89
|
+
const profiles = of('profile').sort((a, b) => dated(a) - dated(b));
|
|
90
|
+
const profile = profiles[0] ?? null;
|
|
91
|
+
const semester = profile ? (profile.props.semester?.trim() || (profile.props.school_start ? semesterAt(profile.props.school_start, opts.date) : null)) : null;
|
|
92
|
+
const same = (n) => !!opts.subject && !!semester && n.props.subject?.trim() === opts.subject && n.props.semester?.trim() === semester;
|
|
93
|
+
const entries = of('subject').filter(same);
|
|
94
|
+
const entry = entries[0] ?? null;
|
|
95
|
+
const memories = of('memory').filter((n) => !!opts.agent && n.props.agent?.trim() === opts.agent);
|
|
96
|
+
const child = of('memory').find((n) => n.props.agent?.trim() === CHILD_MEMORY_AGENT) ?? null;
|
|
97
|
+
const textbooks = of('textbook').filter(same);
|
|
98
|
+
const refs = textbooks.map((n) => n.path);
|
|
99
|
+
for (const n of [profile, entry]) {
|
|
100
|
+
if (!n)
|
|
101
|
+
continue;
|
|
102
|
+
for (const l of wikilinks(n.text)) {
|
|
103
|
+
const p = resolveLink(l, files);
|
|
104
|
+
if (p)
|
|
105
|
+
refs.push(p);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const self = new Set([profile?.path, entry?.path]);
|
|
109
|
+
return {
|
|
110
|
+
profile,
|
|
111
|
+
extraProfiles: profiles.slice(1).map((n) => n.path),
|
|
112
|
+
semester,
|
|
113
|
+
entry,
|
|
114
|
+
extraEntries: entries.slice(1).map((n) => n.path),
|
|
115
|
+
memory: memories[0] ?? null,
|
|
116
|
+
extraMemories: memories.slice(1).map((n) => n.path),
|
|
117
|
+
child,
|
|
118
|
+
refs: [...new Set(refs)].filter((p) => !self.has(p)),
|
|
119
|
+
textbooks,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** 入口文件缺了为什么(进上下文包 entry: 与这条消息的 warnings;家长端就看得到) */
|
|
123
|
+
export function missingEntry(subject, pick) {
|
|
124
|
+
if (!subject)
|
|
125
|
+
return '缺:cotutor.json 里这位老师没配 subject';
|
|
126
|
+
if (!pick.profile)
|
|
127
|
+
return '缺:vault 里没有 cotutor: profile 的档案,算不出学期';
|
|
128
|
+
if (!pick.semester)
|
|
129
|
+
return '缺:档案没写 school_start(或 semester),算不出学期';
|
|
130
|
+
return `缺:vault 里没有 cotutor: subject、subject: ${subject}、semester: ${pick.semester} 的文件`;
|
|
131
|
+
}
|
|
132
|
+
/** 记忆文件缺省位置:记忆/<显示名>.md(显示名里的 / 换掉) */
|
|
133
|
+
export function memoryPath(display) {
|
|
134
|
+
return `记忆/${display.replace(/[\\/:]/g, '-')}.md`;
|
|
135
|
+
}
|
|
136
|
+
/** 新建的记忆文件 */
|
|
137
|
+
export function memoryTemplate(agent, display) {
|
|
138
|
+
return `---
|
|
139
|
+
cotutor: memory
|
|
140
|
+
agent: ${agent}
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
${display}自己记下的,每个话题开头会整篇读到。你可以随便改、删、分小节;新的加在末尾,老师也会改、删这里的任何一行(记账后整理一次)。
|
|
144
|
+
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
/** 孩子的记忆(2026-10-30):`agent: all` 的那篇,缺省在 记忆/孩子.md;满了(列表行到 CHILD_MEMORY_CAP 条)新的不再进,提醒家长删 */
|
|
148
|
+
export const CHILD_MEMORY_AGENT = 'all';
|
|
149
|
+
export const CHILD_MEMORY_PATH = '记忆/孩子.md';
|
|
150
|
+
export const CHILD_MEMORY_CAP = 20;
|
|
151
|
+
/** 新建的孩子的记忆 */
|
|
152
|
+
export function childMemoryTemplate() {
|
|
153
|
+
return `---
|
|
154
|
+
cotutor: memory
|
|
155
|
+
agent: ${CHILD_MEMORY_AGENT}
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
关于孩子本人、换一科也成立的事(情绪、读写、注意力、家里谁在旁边),每位老师每个话题开头都会读到。老师在「## 记忆」里写「孩子:」开头的行,应用记在这里;你可以随便改、删。和档案说的不一样时,以档案为准。最多 ${CHILD_MEMORY_CAP} 条,满了就不再记,删几条才有地方。
|
|
159
|
+
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 往记忆文件末尾追加:每条一行 `- <日期> <原话>`(老师自己写了日期开头就不再加);文里已有同样的话就跳过。
|
|
164
|
+
* cap:列表行最多这么多条,满了的不加,进 full。返回新全文与真加上的行;一条都没加 → text 原样。
|
|
165
|
+
*/
|
|
166
|
+
export function appendMemory(existing, items, date, cap) {
|
|
167
|
+
const has = (s) => existing.split('\n').some((l) => l.replace(/^\s*[-*]\s+(\d{4}-\d{2}-\d{2}\s+)?/, '').trim() === s);
|
|
168
|
+
const added = [];
|
|
169
|
+
const full = [];
|
|
170
|
+
const room = cap === undefined ? Infinity : cap - memoryCount(existing);
|
|
171
|
+
for (const raw of items) {
|
|
172
|
+
const s = raw.replace(/\s+/g, ' ').trim();
|
|
173
|
+
const bare = s.replace(/^\d{4}-\d{2}-\d{2}\s+/, '');
|
|
174
|
+
if (!bare || has(bare) || added.some((a) => a.endsWith(` ${bare}`)))
|
|
175
|
+
continue;
|
|
176
|
+
if (added.length >= room) {
|
|
177
|
+
full.push(bare);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
added.push(`- ${/^\d{4}-\d{2}-\d{2}\s/.test(s) ? s : `${date} ${s}`}`);
|
|
181
|
+
}
|
|
182
|
+
if (!added.length)
|
|
183
|
+
return { text: existing, added, full };
|
|
184
|
+
const base = existing.replace(/\s*$/, '');
|
|
185
|
+
return { text: `${base}\n${/^\s*[-*]\s/.test(base.split('\n').at(-1) ?? '') ? '' : '\n'}${added.join('\n')}\n`, added, full };
|
|
186
|
+
}
|
|
187
|
+
export function parseMemoryOp(item) {
|
|
188
|
+
const s = item.replace(/\s+/g, ' ').trim();
|
|
189
|
+
const del = /^删[::]\s*(.+)$/.exec(s);
|
|
190
|
+
if (del)
|
|
191
|
+
return { op: 'delete', from: del[1].trim() };
|
|
192
|
+
const body = /^改[::]\s*(.+)$/.exec(s)?.[1] ?? '';
|
|
193
|
+
const cuts = [...body.matchAll(/\s*(?:→|->)\s*/g)].map((m) => ({ from: body.slice(0, m.index).trim(), to: body.slice(m.index + m[0].length).trim() })).filter((c) => c.from && c.to);
|
|
194
|
+
if (cuts.length)
|
|
195
|
+
return { op: 'change', ...cuts[0], ...(cuts.length > 1 ? { alt: cuts.slice(1) } : {}) };
|
|
196
|
+
return { op: 'add', text: s };
|
|
197
|
+
}
|
|
198
|
+
/** 一行记忆去掉列表点与日期前缀后的原话(比对用) */
|
|
199
|
+
const bareLine = (l) => l.replace(/^\s*[-*]\s+/, '').replace(/^\d{4}-\d{2}-\d{2}\s+/, '').replace(/\s+/g, ' ').trim();
|
|
200
|
+
/** 一行改动给家长看的样子:新增的原话、「改:旧 → 新」、「删:旧」(家长端「记录」的「记住了」) */
|
|
201
|
+
export function memoryLineText(l) {
|
|
202
|
+
if (l.before === null)
|
|
203
|
+
return bareLine(l.after ?? '');
|
|
204
|
+
if (l.after === null)
|
|
205
|
+
return `删:${bareLine(l.before)}`;
|
|
206
|
+
return `改:${bareLine(l.before)} → ${bareLine(l.after)}`;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 按原话找一行:正文(frontmatter 之后)里原话一字不差的那行;没有就找唯一一行包含它的(原话至少 4 个字);都不是 → -1。
|
|
210
|
+
* 不分老师写的、家长写的(2026-09-18 定:机器一律可以改)。fuzzy = false 只认一字不差的(这轮里家长改过文件,2026-10-30)。
|
|
211
|
+
*/
|
|
212
|
+
export function findMemoryLine(lines, from, bodyStart, fuzzy = true) {
|
|
213
|
+
const want = bareLine(from);
|
|
214
|
+
if (!want)
|
|
215
|
+
return -1;
|
|
216
|
+
const exact = lines.findIndex((l, i) => i >= bodyStart && bareLine(l) === want);
|
|
217
|
+
if (exact >= 0)
|
|
218
|
+
return exact;
|
|
219
|
+
if (!fuzzy || Array.from(want).length < 4)
|
|
220
|
+
return -1;
|
|
221
|
+
const hits = lines.map((l, i) => (i >= bodyStart && l.trim() && bareLine(l).includes(want) ? i : -1)).filter((i) => i >= 0);
|
|
222
|
+
return hits.length === 1 ? hits[0] : -1;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 把一串操作落到记忆全文上:先改、删(按原话找行,见 findMemoryLine),再把新增的追加到末尾(appendMemory,去重)。
|
|
226
|
+
* 改过的列表行换成 `- <今天> 新的`(新的自己带着日期就去掉,不写两个日期);不是列表的行整行换成新的。strict:改、删只认一字不差的原话;cap:新增后最多几条(先删后加,删掉的腾出地方)。
|
|
227
|
+
* 改有几种切法(parseMemoryOp 的 alt)时:先挑原话一字不差的那种;都不是再模糊找,原话长的先(短的是长的前缀,会把原话后半截切进新的里)。
|
|
228
|
+
*/
|
|
229
|
+
export function applyMemoryOps(existing, ops, date, opts = {}) {
|
|
230
|
+
const lines = existing.split('\n');
|
|
231
|
+
const fm = /^\uFEFF?---\s*$/.test(lines[0] ?? '') ? lines.findIndex((l, i) => i > 0 && /^---\s*$/.test(l)) : -1;
|
|
232
|
+
const bodyStart = fm > 0 ? fm + 1 : 0;
|
|
233
|
+
const changes = [];
|
|
234
|
+
const misses = [];
|
|
235
|
+
const edits = [];
|
|
236
|
+
const gone = new Set();
|
|
237
|
+
const locate = (o) => {
|
|
238
|
+
const cuts = o.op === 'change' ? [{ from: o.from, to: o.to }, ...(o.alt ?? [])] : [{ from: o.from, to: '' }];
|
|
239
|
+
const free = (i) => i >= 0 && !gone.has(i);
|
|
240
|
+
for (const c of cuts) {
|
|
241
|
+
const i = findMemoryLine(lines, c.from, bodyStart, false);
|
|
242
|
+
if (free(i))
|
|
243
|
+
return { i, to: c.to };
|
|
244
|
+
}
|
|
245
|
+
if (!opts.strict)
|
|
246
|
+
for (const c of [...cuts].reverse()) {
|
|
247
|
+
const i = findMemoryLine(lines, c.from, bodyStart, true);
|
|
248
|
+
if (free(i))
|
|
249
|
+
return { i, to: c.to };
|
|
250
|
+
}
|
|
251
|
+
return { i: -1, to: '' };
|
|
252
|
+
};
|
|
253
|
+
for (const o of ops) {
|
|
254
|
+
if (o.op === 'add')
|
|
255
|
+
continue;
|
|
256
|
+
const { i, to } = locate(o);
|
|
257
|
+
if (i < 0) {
|
|
258
|
+
misses.push(o.op === 'change' ? `改:${o.from}` : `删:${o.from}`);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const old = bareLine(lines[i]);
|
|
262
|
+
if (o.op === 'delete') {
|
|
263
|
+
gone.add(i);
|
|
264
|
+
changes.push(`删:${old}`);
|
|
265
|
+
edits.push({ before: lines[i], after: null });
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
const bullet = /^(\s*[-*]\s+)/.exec(lines[i]);
|
|
269
|
+
const before = lines[i];
|
|
270
|
+
const fresh = to.replace(/^\d{4}-\d{2}-\d{2}\s+/, '');
|
|
271
|
+
lines[i] = bullet ? `${bullet[1]}${date} ${fresh}` : fresh;
|
|
272
|
+
changes.push(`改:${old} → ${fresh}`);
|
|
273
|
+
edits.push({ before, after: lines[i] });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const kept = lines.filter((_, i) => !gone.has(i)).join('\n');
|
|
277
|
+
const adds = ops.flatMap((o) => (o.op === 'add' ? [o.text] : []));
|
|
278
|
+
const r = appendMemory(kept, adds, date, opts.cap);
|
|
279
|
+
return { text: r.text, changes: [...changes, ...r.added], misses, full: r.full, lines: [...edits, ...r.added.map((after) => ({ before: null, after }))] };
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* 撤销一串改动(删话题时,2026-10-05):倒着来——改了的换回原来那行,新增的删掉,删了的接回末尾(原来的位置不记)。
|
|
283
|
+
* 按整行原文找;家长或整理那轮后来又改过那行就找不到,进 misses,不动。
|
|
284
|
+
*/
|
|
285
|
+
export function undoMemoryLines(existing, edits) {
|
|
286
|
+
let lines = existing.split('\n');
|
|
287
|
+
let undone = 0;
|
|
288
|
+
const misses = [];
|
|
289
|
+
const back = [];
|
|
290
|
+
for (const e of [...edits].reverse()) {
|
|
291
|
+
if (e.after === null) {
|
|
292
|
+
if (e.before !== null) {
|
|
293
|
+
back.unshift(e.before);
|
|
294
|
+
undone++;
|
|
295
|
+
}
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
const i = lines.findIndex((l) => l === e.after);
|
|
299
|
+
if (i < 0) {
|
|
300
|
+
misses.push(bareLine(e.after));
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
lines = e.before === null ? lines.filter((_, k) => k !== i) : lines.map((l, k) => (k === i ? e.before : l));
|
|
304
|
+
undone++;
|
|
305
|
+
}
|
|
306
|
+
let text = lines.join('\n');
|
|
307
|
+
if (back.length) {
|
|
308
|
+
const base = text.replace(/\s*$/, '');
|
|
309
|
+
text = `${base}\n${/^\s*[-*]\s/.test(base.split('\n').at(-1) ?? '') ? '' : '\n'}${back.join('\n')}\n`;
|
|
310
|
+
}
|
|
311
|
+
return { text, undone, misses };
|
|
312
|
+
}
|
|
313
|
+
/** 记忆文件里有几条(frontmatter 之后的列表行) */
|
|
314
|
+
export function memoryCount(text) {
|
|
315
|
+
const body = text.replace(/^\uFEFF?---\s*\n[\s\S]*?\n---\s*(\n|$)/, '');
|
|
316
|
+
return body.split('\n').filter((l) => /^\s*[-*]\s+\S/.test(l)).length;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* 记账后整理记忆那轮的消息正文(2026-09-18):新会话、from: system;记忆原文在上下文包的 <vault-note role="memory">。
|
|
320
|
+
* 回的「## 记忆」段不受每轮条数上限,应用照单落盘、不问家长(家长在 Obsidian 里兜底)。
|
|
321
|
+
*/
|
|
322
|
+
export function tidyMemoryPrompt(opts) {
|
|
323
|
+
return [
|
|
324
|
+
`学习结束、账记完了,把你的记忆整理一遍。记忆文件的原文在上下文包的 <vault-note role="memory">(现在 ${opts.count} 条;截了就自己 Read 全文),今天(${opts.date})的日记在 ${opts.diaryFile},读你这一科的几段对照一下。`,
|
|
325
|
+
'',
|
|
326
|
+
'只回一段「## 记忆」,一行一条,别的一个字都不用写:',
|
|
327
|
+
'',
|
|
328
|
+
'## 记忆',
|
|
329
|
+
'- 删:原话(过时的、今天看出来不对的、和别的重复的)',
|
|
330
|
+
'- 改:原话 → 新的(要更新的,比如「还没学竖式 → 9 月中学会了两位数竖式」;几条说一件事就改成一条、删掉其余)',
|
|
331
|
+
'- 新的一条(今天日记里看出来、以后还用得上、记忆里还没有的)',
|
|
332
|
+
'',
|
|
333
|
+
`原话照记忆文件里那一行抄,日期可以不抄;谁写的行都可以改、删。整理完不超过 ${opts.cap} 条。都不用动就只回一句「记忆不用整理」,不写「## 记忆」段。`,
|
|
334
|
+
].join('\n');
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* 按 entryChars 截一篇笔记带进上下文包。档案、入口文件留开头(家长写在前面的最要紧);
|
|
338
|
+
* 记忆留末尾——应用往末尾追加,最新的在后面,截开头丢的是旧的(2026-09-18 之前留的是开头,越记越看不到新的)。
|
|
339
|
+
* 末尾那头从一行的开头起,不截半行。
|
|
340
|
+
*/
|
|
341
|
+
export function clipNote(text, limit, keep) {
|
|
342
|
+
if (text.length <= limit)
|
|
343
|
+
return { text, cut: false };
|
|
344
|
+
if (keep === 'head')
|
|
345
|
+
return { text: `${text.slice(0, limit)}\n……(后面截掉了,要看全文自己 Read)`, cut: true };
|
|
346
|
+
const tail = text.slice(-limit);
|
|
347
|
+
const nl = tail.indexOf('\n');
|
|
348
|
+
const aligned = text.at(-limit - 1) === '\n' || nl < 0 ? tail : tail.slice(nl + 1);
|
|
349
|
+
return { text: `……(前面旧的截掉了,下面是最近的;要看全文自己 Read)\n${aligned}`, cut: true };
|
|
350
|
+
}
|
|
351
|
+
/** 短 hash(FNV-1a 32 位):同一话题里判断「这篇上次带过、没改」 */
|
|
352
|
+
export function textHash(s) {
|
|
353
|
+
let h = 0x811c9dc5;
|
|
354
|
+
for (let i = 0; i < s.length; i++) {
|
|
355
|
+
h ^= s.charCodeAt(i);
|
|
356
|
+
h = Math.imul(h, 0x01000193);
|
|
357
|
+
}
|
|
358
|
+
return (h >>> 0).toString(16).padStart(8, '0');
|
|
359
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type MemoryLine, type VaultNote } from './vault-notes.ts';
|
|
2
|
+
import type { ConversationMessage, PathRole } from '../schema/index.ts';
|
|
3
|
+
/** vault 在哪:workspace 的 paths(vault、diary、plans、textbooks…);传整个 workspace 也行 */
|
|
4
|
+
export interface Vault {
|
|
5
|
+
paths: Readonly<Record<PathRole, string>>;
|
|
6
|
+
}
|
|
7
|
+
/** 删话题撤销了多少:记忆几行、日记几段;找不到原文没撤的(家长或整理那轮后来改过)一条一句 */
|
|
8
|
+
export interface ThreadUndo {
|
|
9
|
+
memory: number;
|
|
10
|
+
diary: number;
|
|
11
|
+
misses: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 删话题时撤回它留在 vault 里的:各轮写进记忆的行(memoryLines;孩子的记忆是 childLines)倒着撤、记账写进日记的那段(diaryBlock)摘掉;
|
|
15
|
+
* 找不到原文的(家长或整理那轮后来改过)不撤,一条一句列进 misses
|
|
16
|
+
*/
|
|
17
|
+
export declare function undoThreadVault(v: Vault, tutor: string, date: string, gone: readonly ConversationMessage[]): Promise<ThreadUndo>;
|
|
18
|
+
/** 这几天的日记(<日记目录>/<日期>.md);没有的跳过 */
|
|
19
|
+
export declare function readDiaries(v: Vault, dates: readonly string[]): Promise<{
|
|
20
|
+
date: string;
|
|
21
|
+
text: string;
|
|
22
|
+
}[]>;
|
|
23
|
+
/** 当天的日记:update 拿现有内容(没有 → null)回新内容;先 .tmp 再 rename。返回文件名(<日期>.md) */
|
|
24
|
+
export declare function writeDiary(v: Vault, date: string, update: (existing: string | null) => string): Promise<string>;
|
|
25
|
+
/** 教材目录下的每册文件(<教材目录>/<册>.md),给 textbookHeadings;没有目录 → [] */
|
|
26
|
+
export declare function readTextbooks(v: Vault): Promise<{
|
|
27
|
+
name: string;
|
|
28
|
+
text: string;
|
|
29
|
+
}[]>;
|
|
30
|
+
/**
|
|
31
|
+
* 扫 vault:所有文件的相对路径(解析 [[链接]] 用)+ 带 `cotutor:` 属性的 md(按属性定位,《obsidian仓库设计.md》2026-09-17)。
|
|
32
|
+
* 跳过点开头的目录(.obsidian / .git)与日记、计划目录(机器写的,不带属性,越积越多)。读不到的文件跳过;vault 不在 → 全空。
|
|
33
|
+
*/
|
|
34
|
+
export declare function scanVault(v: Vault): Promise<{
|
|
35
|
+
notes: VaultNote[];
|
|
36
|
+
files: string[];
|
|
37
|
+
}>;
|
|
38
|
+
/** 要写进记忆文件的一次改动(还没写):planVaultMemory 算,writeVaultMemory 写 */
|
|
39
|
+
export interface MemoryPlan {
|
|
40
|
+
/** 相对 vault 根 */
|
|
41
|
+
file: string;
|
|
42
|
+
/** 算的时候文件的原文;新建 = null */
|
|
43
|
+
base: string | null;
|
|
44
|
+
text: string;
|
|
45
|
+
changes: string[];
|
|
46
|
+
lines: MemoryLine[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 「## 记忆」段 → 这位 agent 的记忆文件要怎么改(按 `cotutor: memory` + `agent:` 找;没有就建 记忆/<显示名>.md,孩子的记忆建 记忆/孩子.md),只算不写:
|
|
50
|
+
* 新增追加到末尾,「改:」「删:」按原话找行改、删(任何一行都能动,2026-09-18);缺省位置已有一篇没属性的同名文件就不碰,进提醒。
|
|
51
|
+
* seen = 这一轮上下文包里老师看到的那版(截过的那段的 textHash 与截的字数):文件和它对不上 = 这轮里家长改过,
|
|
52
|
+
* 改、删只认一字不差的原话,找不到的不改——按「包含」找会把家长刚补上的半句一起盖掉(2026-10-30)。
|
|
53
|
+
* 孩子的记忆(agent: all)最多 CHILD_MEMORY_CAP 条,满了新增的不进,提醒家长删几条。
|
|
54
|
+
*/
|
|
55
|
+
export declare function planVaultMemory(v: Vault, o: {
|
|
56
|
+
agent: string;
|
|
57
|
+
display: string;
|
|
58
|
+
items: readonly string[];
|
|
59
|
+
date: string;
|
|
60
|
+
seen?: {
|
|
61
|
+
path: string;
|
|
62
|
+
hash: string;
|
|
63
|
+
clip: number;
|
|
64
|
+
};
|
|
65
|
+
}): Promise<{
|
|
66
|
+
plan: MemoryPlan | null;
|
|
67
|
+
warnings: string[];
|
|
68
|
+
}>;
|
|
69
|
+
/** 写下 planVaultMemory 算好的:先重读,和算的时候不一样(家长刚存了一版)就不写,回为什么;写成回 null。先 .tmp 再 rename */
|
|
70
|
+
export declare function writeVaultMemory(v: Vault, plan: MemoryPlan): Promise<string | null>;
|