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
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const LOG_KEEP_DAYS = 14;
|
|
2
|
+
/** 删 keepDays 天以前的(按文件名的日期,不看修改时间);返回删了哪些 */
|
|
3
|
+
export declare function pruneLogs(dir: string, now: Date, keepDays?: number): string[];
|
|
4
|
+
/** 今天写的是哪个文件 */
|
|
5
|
+
export declare const logFileFor: (dir: string, now: Date) => string;
|
|
6
|
+
/**
|
|
7
|
+
* 把 process.stdout / stderr 改写进按天的文件(不再写到原来的地方,免得 launchd.log 里再有一份);返回撤掉的函数(测试用)。
|
|
8
|
+
* 一行开头加「时:分:秒 」;一次写进来的不一定是整行,接着上一次的不再加
|
|
9
|
+
*/
|
|
10
|
+
export declare function teeLogs(dir: string, opts?: {
|
|
11
|
+
now?: () => Date;
|
|
12
|
+
keepDays?: number;
|
|
13
|
+
}): () => void;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后台服务的日志(cotutor serve --log-dir <目录>,cotutor service 装的就带它):stdout / stderr 改写进 <目录>/<日期>.log,一天一个,每行带时分秒;
|
|
3
|
+
* 留 LOG_KEEP_DAYS 天,起来时、换天时删更早的。一跑几个星期,不按天切就一个文件越长越大(launchd、systemd 都不替你切)。
|
|
4
|
+
* 起来之前的输出(node 自己报的、模块没加载上)还是走原来的 stdout / stderr:macOS 是 launchd 接着的 <目录>/launchd.log,Linux 是 journal。
|
|
5
|
+
*/
|
|
6
|
+
import { closeSync, mkdirSync, openSync, readdirSync, rmSync, writeSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { localDate } from "../../shared/time.js";
|
|
9
|
+
export const LOG_KEEP_DAYS = 14;
|
|
10
|
+
const LOG_RE = /^(\d{4}-\d{2}-\d{2})\.log$/;
|
|
11
|
+
/** 删 keepDays 天以前的(按文件名的日期,不看修改时间);返回删了哪些 */
|
|
12
|
+
export function pruneLogs(dir, now, keepDays = LOG_KEEP_DAYS) {
|
|
13
|
+
const oldest = localDate(new Date(now.getTime() - (keepDays - 1) * 86_400_000));
|
|
14
|
+
const gone = [];
|
|
15
|
+
let names = [];
|
|
16
|
+
try {
|
|
17
|
+
names = readdirSync(dir);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return gone;
|
|
21
|
+
}
|
|
22
|
+
for (const f of names) {
|
|
23
|
+
const m = LOG_RE.exec(f);
|
|
24
|
+
if (m && m[1] < oldest) {
|
|
25
|
+
rmSync(join(dir, f), { force: true });
|
|
26
|
+
gone.push(f);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return gone;
|
|
30
|
+
}
|
|
31
|
+
/** 今天写的是哪个文件 */
|
|
32
|
+
export const logFileFor = (dir, now) => join(dir, `${localDate(now)}.log`);
|
|
33
|
+
/**
|
|
34
|
+
* 把 process.stdout / stderr 改写进按天的文件(不再写到原来的地方,免得 launchd.log 里再有一份);返回撤掉的函数(测试用)。
|
|
35
|
+
* 一行开头加「时:分:秒 」;一次写进来的不一定是整行,接着上一次的不再加
|
|
36
|
+
*/
|
|
37
|
+
export function teeLogs(dir, opts = {}) {
|
|
38
|
+
const now = opts.now ?? (() => new Date());
|
|
39
|
+
mkdirSync(dir, { recursive: true });
|
|
40
|
+
let day = '';
|
|
41
|
+
let fd = null;
|
|
42
|
+
let atLineStart = true;
|
|
43
|
+
const open = (d) => {
|
|
44
|
+
const today = localDate(d);
|
|
45
|
+
if (fd !== null && today === day)
|
|
46
|
+
return fd;
|
|
47
|
+
if (fd !== null)
|
|
48
|
+
closeSync(fd);
|
|
49
|
+
day = today;
|
|
50
|
+
fd = openSync(logFileFor(dir, d), 'a');
|
|
51
|
+
pruneLogs(dir, d, opts.keepDays);
|
|
52
|
+
return fd;
|
|
53
|
+
};
|
|
54
|
+
const write = (chunk, encoding) => {
|
|
55
|
+
const text = typeof chunk === 'string' ? chunk : Buffer.isBuffer(chunk) || chunk instanceof Uint8Array ? Buffer.from(chunk).toString(typeof encoding === 'string' ? encoding : 'utf8') : String(chunk);
|
|
56
|
+
if (!text)
|
|
57
|
+
return;
|
|
58
|
+
const d = now();
|
|
59
|
+
const stamp = `${[d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, '0')).join(':')} `;
|
|
60
|
+
let out = '';
|
|
61
|
+
for (const part of text.split(/(?<=\n)/)) {
|
|
62
|
+
out += (atLineStart ? stamp : '') + part;
|
|
63
|
+
atLineStart = part.endsWith('\n');
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
writeSync(open(d), out);
|
|
67
|
+
}
|
|
68
|
+
catch { /* 写不了日志不能把服务带倒 */ }
|
|
69
|
+
};
|
|
70
|
+
const wrap = (stream) => {
|
|
71
|
+
const original = stream.write;
|
|
72
|
+
stream.write = ((chunk, encoding, cb) => {
|
|
73
|
+
write(chunk, encoding);
|
|
74
|
+
const done = typeof encoding === 'function' ? encoding : cb;
|
|
75
|
+
if (typeof done === 'function')
|
|
76
|
+
queueMicrotask(() => done());
|
|
77
|
+
return true;
|
|
78
|
+
});
|
|
79
|
+
return () => { stream.write = original; };
|
|
80
|
+
};
|
|
81
|
+
const undo = [wrap(process.stdout), wrap(process.stderr)];
|
|
82
|
+
open(now());
|
|
83
|
+
return () => {
|
|
84
|
+
for (const u of undo)
|
|
85
|
+
u();
|
|
86
|
+
if (fd !== null)
|
|
87
|
+
closeSync(fd);
|
|
88
|
+
fd = null;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type Server } from 'node:http';
|
|
2
|
+
import { siteUrl } from '../../shared/site-url.ts';
|
|
3
|
+
import type { ListenInfo } from '../../ui/parent/qr-page.ts';
|
|
4
|
+
import { type AppContext } from '../http/app.ts';
|
|
5
|
+
import { type ResolveOptions, type Workspace } from '../workspace.ts';
|
|
6
|
+
export { siteUrl };
|
|
7
|
+
export interface ServeOptions extends ResolveOptions {
|
|
8
|
+
workspace?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
host?: string;
|
|
11
|
+
/** 强制走 HTTP(哪怕证书在) */
|
|
12
|
+
http?: boolean;
|
|
13
|
+
/** 有事时拦着睡眠;缺省开 */
|
|
14
|
+
awake?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ServeResult {
|
|
17
|
+
server: Server;
|
|
18
|
+
ctx: AppContext;
|
|
19
|
+
ws: Workspace;
|
|
20
|
+
port: number;
|
|
21
|
+
https: boolean;
|
|
22
|
+
/** 本机名与局域网 IPv4 各一条 */
|
|
23
|
+
urls: string[];
|
|
24
|
+
/** 家长端首页:在这台电脑上打开的那条(localhost,证书里签了);serve 只打印它,扫码在它里面 */
|
|
25
|
+
parentPage: string;
|
|
26
|
+
warnings: string[];
|
|
27
|
+
}
|
|
28
|
+
/** 证书路径:cotutor.json 的 server.https 优先(相对 workspace 根),否则机器级 ~/.config/cotutor/certs/;都没有 → null */
|
|
29
|
+
export declare function httpsFiles(ws: Workspace): {
|
|
30
|
+
cert: string;
|
|
31
|
+
key: string;
|
|
32
|
+
} | null;
|
|
33
|
+
/** 局域网 IPv4(iPad / iPhone 用它访问;.local 名不一定解析得到,有些设备还会挑中走不通的 IPv6) */
|
|
34
|
+
export declare function lanAddresses(): string[];
|
|
35
|
+
/**
|
|
36
|
+
* 这台电脑在局域网里的名字(不带 .local)。macOS 读「本地主机名」(系统设置 › 通用 › 共享 里那个,就是 Bonjour 名,改了系统才变);
|
|
37
|
+
* 别的系统用 os.hostname()。读不到退回 os.hostname()。serve、证书、二维码都从这里拿
|
|
38
|
+
*/
|
|
39
|
+
export declare function computerName(platform?: NodeJS.Platform, read?: () => string, fallback?: string): string;
|
|
40
|
+
/** 本机的 mDNS 名(与 cotutor cert 签的那条同一个写法) */
|
|
41
|
+
export declare function localName(name?: string): string;
|
|
42
|
+
/** 证书认不认这个主机名;读不了当作不认 */
|
|
43
|
+
export declare function certCovers(certFile: string, host: string): boolean;
|
|
44
|
+
/** 扫码页要的三样;listen 之后才知道真端口 */
|
|
45
|
+
export declare function listenInfo(https: boolean, port: number): ListenInfo;
|
|
46
|
+
export declare function serveWorkspace(opts?: ServeOptions): Promise<ServeResult>;
|
|
47
|
+
/**
|
|
48
|
+
* busy() 为真就起一个拦闲置睡眠的子进程,为假就停;serve 没了它自己退:macOS 是 caffeinate -i -w <pid>,Windows 是一段 PowerShell(service-windows.ts 的 awakeScript);Linux 什么都不做。
|
|
49
|
+
* 合盖照样睡(那是家长的事,iPad 那篇写着);返回停掉的函数
|
|
50
|
+
*/
|
|
51
|
+
export declare function holdAwake(busy: () => boolean, platform?: NodeJS.Platform, everyMs?: number): () => void;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cotutor serve:一 workspace 一进程,端口读 cotutor.json(--port 覆盖)。
|
|
3
|
+
* 启动打印解析结果与体检警告(配置坏了直接不起,骨架缺失只警告)。
|
|
4
|
+
* 扫码页:/qr 现画一张二维码(编 <电脑名>.local 那条,不随 Wi-Fi 变),iPad 用相机扫;listen 之后把真端口交给 ctx.listen。端口是 443 时地址里不写端口(siteUrl)。
|
|
5
|
+
* HTTPS(iPad 上录音要):server.https 指了证书就用它(单个 workspace 的例外);没指就看机器级 ~/.config/cotutor/certs/(cotutor cert 用 mkcert 建);都没有走 HTTP。
|
|
6
|
+
* 有通话开着、或有老师在写,就拦着这台电脑闲置睡眠(macOS caffeinate -i,Windows SetThreadExecutionState);闲着不拦(家长定)。网络流量挡不住闲置睡眠,上着课没人碰电脑也会睡过去。
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
9
|
+
import { X509Certificate } from 'node:crypto';
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
11
|
+
import { createServer as createHttp } from 'node:http';
|
|
12
|
+
import { createServer as createHttps } from 'node:https';
|
|
13
|
+
import { hostname, networkInterfaces } from 'node:os';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { siteUrl } from "../../shared/site-url.js";
|
|
16
|
+
import { doctorWorkspace } from "./doctor.js";
|
|
17
|
+
import { answersLocally } from "./port.js";
|
|
18
|
+
import { awakeScript, psArgs } from "./service-windows.js";
|
|
19
|
+
import { createContext, createHandler } from "../http/app.js";
|
|
20
|
+
import { liveUpgrade } from "../ws/route.js";
|
|
21
|
+
import { AUTO_BOOKKEEP_EVERY_MS, autoBookkeep } from "../../runtime/auto-bookkeep.js";
|
|
22
|
+
import { USER_CERT_DIR, expandPath, loadWorkspace } from "../workspace.js";
|
|
23
|
+
export { siteUrl };
|
|
24
|
+
/** 证书路径:cotutor.json 的 server.https 优先(相对 workspace 根),否则机器级 ~/.config/cotutor/certs/;都没有 → null */
|
|
25
|
+
export function httpsFiles(ws) {
|
|
26
|
+
const h = ws.config.server.https;
|
|
27
|
+
if (h)
|
|
28
|
+
return { cert: expandPath(h.cert, ws.root), key: expandPath(h.key, ws.root) };
|
|
29
|
+
const cert = join(USER_CERT_DIR, 'cert.pem');
|
|
30
|
+
const key = join(USER_CERT_DIR, 'key.pem');
|
|
31
|
+
try {
|
|
32
|
+
readFileSync(cert);
|
|
33
|
+
readFileSync(key);
|
|
34
|
+
return { cert, key };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** 局域网 IPv4(iPad / iPhone 用它访问;.local 名不一定解析得到,有些设备还会挑中走不通的 IPv6) */
|
|
41
|
+
export function lanAddresses() {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const list of Object.values(networkInterfaces()))
|
|
44
|
+
for (const i of list ?? [])
|
|
45
|
+
if (i.family === 'IPv4' && !i.internal)
|
|
46
|
+
out.push(i.address);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 这台电脑在局域网里的名字(不带 .local)。macOS 读「本地主机名」(系统设置 › 通用 › 共享 里那个,就是 Bonjour 名,改了系统才变);
|
|
51
|
+
* 别的系统用 os.hostname()。读不到退回 os.hostname()。serve、证书、二维码都从这里拿
|
|
52
|
+
*/
|
|
53
|
+
export function computerName(platform = process.platform, read = () => execFileSync('/usr/sbin/scutil', ['--get', 'LocalHostName'], { encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'] }), fallback = hostname()) {
|
|
54
|
+
if (platform === 'darwin') {
|
|
55
|
+
try {
|
|
56
|
+
const name = read().trim();
|
|
57
|
+
if (name)
|
|
58
|
+
return name;
|
|
59
|
+
}
|
|
60
|
+
catch { /* 没设过本地主机名 */ }
|
|
61
|
+
}
|
|
62
|
+
return fallback.replace(/\.local$/i, '');
|
|
63
|
+
}
|
|
64
|
+
/** 读 scutil 要起一个进程,登录、发一条这些请求里都会问到:记一分钟 */
|
|
65
|
+
let nameCache = null;
|
|
66
|
+
function currentName() {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
if (!nameCache || now - nameCache.at > 60_000)
|
|
69
|
+
nameCache = { at: now, name: computerName() };
|
|
70
|
+
return nameCache.name;
|
|
71
|
+
}
|
|
72
|
+
/** 本机的 mDNS 名(与 cotutor cert 签的那条同一个写法) */
|
|
73
|
+
export function localName(name = currentName()) {
|
|
74
|
+
return name.endsWith('.local') ? name : `${name}.local`;
|
|
75
|
+
}
|
|
76
|
+
/** 证书认不认这个主机名;读不了当作不认 */
|
|
77
|
+
export function certCovers(certFile, host) {
|
|
78
|
+
try {
|
|
79
|
+
return new X509Certificate(readFileSync(certFile)).checkHost(host) !== undefined;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** 扫码页要的三样;listen 之后才知道真端口 */
|
|
86
|
+
export function listenInfo(https, port) {
|
|
87
|
+
const scheme = https ? 'https' : 'http';
|
|
88
|
+
const ip = lanAddresses()[0];
|
|
89
|
+
return { name: siteUrl(scheme, localName(), port), ip: ip ? siteUrl(scheme, ip, port) : null, https };
|
|
90
|
+
}
|
|
91
|
+
export async function serveWorkspace(opts = {}) {
|
|
92
|
+
const ws = loadWorkspace(opts.workspace, opts);
|
|
93
|
+
// 不探 CLI(起服务不用等它);防火墙要查:平板连不上时这里是家长唯一看得到提醒的地方
|
|
94
|
+
const report = await doctorWorkspace(ws.root, { ...opts, probeEnv: false, firewall: true });
|
|
95
|
+
const warnings = report.checks.filter((c) => !c.ok).map((c) => `${c.name}:${c.detail}${c.fix ? `(${c.fix})` : ''}`);
|
|
96
|
+
const port = opts.port ?? ws.config.server.port;
|
|
97
|
+
const ctx = createContext(ws);
|
|
98
|
+
ctx.openCalls = () => liveUpgrade.openCalls();
|
|
99
|
+
const handler = createHandler(ctx);
|
|
100
|
+
const tls = opts.http ? null : httpsFiles(ws);
|
|
101
|
+
const server = tls ? createHttps({ cert: readFileSync(tls.cert), key: readFileSync(tls.key) }, handler) : createHttp(handler);
|
|
102
|
+
// WebSocket:实时老师的那条线(src/app/ws/);不认就关掉
|
|
103
|
+
server.on('upgrade', (req, socket, head) => { void liveUpgrade(req, socket, head, ctx).then((took) => { if (!took)
|
|
104
|
+
socket.destroy(); }, () => socket.destroy()); });
|
|
105
|
+
// 别的程序只占着 127.0.0.1 时,绑通配地址照样成功:平板连到这边,这台电脑上开 localhost 却到了别的程序。先问一声,当被占处理(main.ts 接)
|
|
106
|
+
if (port !== 0 && (await answersLocally(port)))
|
|
107
|
+
throw Object.assign(new Error(`port ${port} answers on 127.0.0.1`), { code: 'EADDRINUSE', port });
|
|
108
|
+
await new Promise((resolveListen, reject) => {
|
|
109
|
+
server.once('error', reject);
|
|
110
|
+
server.listen(port, opts.host ?? '0.0.0.0', () => resolveListen());
|
|
111
|
+
});
|
|
112
|
+
const actual = server.address().port;
|
|
113
|
+
const scheme = tls ? 'https' : 'http';
|
|
114
|
+
const urls = [localName(), ...lanAddresses()].map((h) => siteUrl(scheme, h, actual));
|
|
115
|
+
ctx.listen = () => listenInfo(Boolean(tls), actual);
|
|
116
|
+
// 自动记账(cotutor.json vault.autoBookkeep,缺省关;src/runtime/auto-bookkeep.ts):隔一阵看一次,开关跟着 cotutor.json 热重载;上一次没跑完不叠
|
|
117
|
+
let booking = false;
|
|
118
|
+
const timer = setInterval(() => {
|
|
119
|
+
if (booking)
|
|
120
|
+
return;
|
|
121
|
+
booking = true;
|
|
122
|
+
void (async () => {
|
|
123
|
+
await ctx.reload();
|
|
124
|
+
await autoBookkeep(ctx.runner, ctx.ws, ctx.now());
|
|
125
|
+
})().catch(() => undefined).finally(() => { booking = false; });
|
|
126
|
+
}, AUTO_BOOKKEEP_EVERY_MS);
|
|
127
|
+
timer.unref();
|
|
128
|
+
server.once('close', () => clearInterval(timer));
|
|
129
|
+
if (opts.awake !== false) {
|
|
130
|
+
const stop = holdAwake(() => liveUpgrade.openCalls() > 0 || Object.keys(ctx.ws.config.tutors).some((t) => ctx.runner.running(t) !== null));
|
|
131
|
+
server.once('close', stop);
|
|
132
|
+
}
|
|
133
|
+
if (tls && !certCovers(tls.cert, localName()))
|
|
134
|
+
warnings.push(`证书不含 ${localName()}:多半是电脑名变了(改过名,或局域网里有同名设备时 macOS 会自动加 -2),扫码打开会报「不安全」。重跑 cotutor cert 再重启服务,平板重新扫码`);
|
|
135
|
+
return { server, ctx, ws, port: actual, https: Boolean(tls), urls, parentPage: siteUrl(scheme, 'localhost', actual, '/parent/home'), warnings };
|
|
136
|
+
}
|
|
137
|
+
/** 多久看一次有没有事 */
|
|
138
|
+
const AWAKE_CHECK_MS = 15_000;
|
|
139
|
+
/**
|
|
140
|
+
* busy() 为真就起一个拦闲置睡眠的子进程,为假就停;serve 没了它自己退:macOS 是 caffeinate -i -w <pid>,Windows 是一段 PowerShell(service-windows.ts 的 awakeScript);Linux 什么都不做。
|
|
141
|
+
* 合盖照样睡(那是家长的事,iPad 那篇写着);返回停掉的函数
|
|
142
|
+
*/
|
|
143
|
+
export function holdAwake(busy, platform = process.platform, everyMs = AWAKE_CHECK_MS) {
|
|
144
|
+
if (platform !== 'darwin' && platform !== 'win32')
|
|
145
|
+
return () => { };
|
|
146
|
+
const start = () => (platform === 'darwin'
|
|
147
|
+
? spawn('/usr/bin/caffeinate', ['-i', '-w', String(process.pid)], { stdio: 'ignore' })
|
|
148
|
+
: spawn('powershell.exe', psArgs(awakeScript(process.pid)), { stdio: 'ignore', windowsHide: true }));
|
|
149
|
+
let child = null;
|
|
150
|
+
const tick = () => {
|
|
151
|
+
const b = busy();
|
|
152
|
+
if (b && !child) {
|
|
153
|
+
const c = start();
|
|
154
|
+
c.on('error', () => { if (child === c)
|
|
155
|
+
child = null; });
|
|
156
|
+
c.on('exit', () => { if (child === c)
|
|
157
|
+
child = null; });
|
|
158
|
+
child = c;
|
|
159
|
+
}
|
|
160
|
+
else if (!b && child) {
|
|
161
|
+
child.kill();
|
|
162
|
+
child = null;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const timer = setInterval(tick, everyMs);
|
|
166
|
+
timer.unref();
|
|
167
|
+
return () => { clearInterval(timer); child?.kill(); child = null; };
|
|
168
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cotutor service 在 Windows 上要的几样(service.ts 接这里):
|
|
3
|
+
* 登录时起来:写用户自己的注册表 HKCU\...\Run(不要管理员)。不用计划任务:登录触发对普通令牌可能要管理员,缺省还有 3 天超时、低优先级要逐项改。
|
|
4
|
+
* 没有窗口:Run 里是 wscript.exe 跑一个 JScript 启动器,WScript.Shell.Run(命令, 0) 起 node,控制台藏着;node 的子进程跟着用这个藏着的控制台,不另弹窗。
|
|
5
|
+
* 不用 conhost --headless(2026-11-06 Windows 11 build 26300 上直接以 0 退、node 根本没起,本来也没写进文档);不用 VBScript(微软在逐步下线);不用 powershell -WindowStyle Hidden(会闪一下)。
|
|
6
|
+
* 崩了再起:看护进程 cotutor service run(service.ts 的 runKeeper,一个 node),起 serve,非 0 隔 10 秒再起,0 不起,和 launchd、systemd 同样的说法。
|
|
7
|
+
* 停:按命令行找这个 workspace 的看护进程与 serve(PowerShell,输出不随系统语言变),taskkill /T /F。
|
|
8
|
+
* 这里全是拼字符串与读输出的纯函数,真跑在 service.ts。
|
|
9
|
+
*/
|
|
10
|
+
/** 一个参数写进命令行(CommandLineToArgvW 的规矩:引号前的反斜杠翻倍再转义引号,结尾的反斜杠翻倍) */
|
|
11
|
+
export declare function winQuote(a: string): string;
|
|
12
|
+
export declare const winCommandLine: (args: string[]) => string;
|
|
13
|
+
/** 启动器的内容:wscript 跑它,藏着窗口起 args;第二行记着 args,找服务时读回来 */
|
|
14
|
+
export declare function windowsLauncher(args: string[], root: string): string;
|
|
15
|
+
/** 启动器存成 UTF-16 带 BOM:wscript 按这个读,路径里的中文才对(UTF-8 它按系统代码页读) */
|
|
16
|
+
export declare const encodeLauncher: (text: string) => Buffer;
|
|
17
|
+
/** 读服务文件:带 UTF-16 的 BOM 就按它解,别的按 UTF-8 */
|
|
18
|
+
export declare function decodeServiceFile(buf: Buffer): string;
|
|
19
|
+
/** 从启动器里读回 args;不是启动器 → null */
|
|
20
|
+
export declare function launcherArgs(text: string): string[] | null;
|
|
21
|
+
export declare const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
|
22
|
+
/**
|
|
23
|
+
* 任务管理器「启动应用」里关掉一条,Run 项还在,只在这里记一笔:值的第一个字节单数 = 关了(02 开、03 关;2026-11-06 那台机器上 Docker Desktop 就是 03)。
|
|
24
|
+
* 那里显示的名字是 wscript.exe 的文件描述(Microsoft ® Windows Based Script Host),不是 Run 项的名字,看不出是 cotutor,所以要靠 service status 来说
|
|
25
|
+
*/
|
|
26
|
+
export declare const STARTUP_APPROVED_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run";
|
|
27
|
+
/** reg query 这个值的输出:被关掉了没有(没这个值 = 没关) */
|
|
28
|
+
export declare function startupDisabled(regQuery: string): boolean;
|
|
29
|
+
/** Run 里写的那条 */
|
|
30
|
+
export declare const runValue: (wscript: string, file: string) => string;
|
|
31
|
+
/** 跑一段 PowerShell 的参数:编码传进去不用管引号,输出定成 UTF-8,关掉进度(第一次用模块时它往 stderr 写一堆) */
|
|
32
|
+
export declare function psArgs(script: string): string[];
|
|
33
|
+
/** 找这个 workspace 的看护进程(service run)与它起的 serve(带 --log-dir;终端里的 cotutor serve 不算) */
|
|
34
|
+
export declare function findProcsScript(root: string): string;
|
|
35
|
+
export interface WinProc {
|
|
36
|
+
pid: number;
|
|
37
|
+
keeper: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** 上面那段的输出;坏的、空的当没有 */
|
|
40
|
+
export declare function parseProcs(text: string): WinProc[];
|
|
41
|
+
/**
|
|
42
|
+
* 拦着闲置睡眠(同 macOS 的 caffeinate -i):SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) 之后等 serve 退出。
|
|
43
|
+
* 状态跟着这个线程走:进程被杀或 serve 没了就撤掉
|
|
44
|
+
*/
|
|
45
|
+
export declare function awakeScript(pid: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* powercfg /query SCHEME_CURRENT SUB_SLEEP STANDBYIDLE:接着电源几秒没人碰就睡(0 = 不睡);读不出 → null。
|
|
48
|
+
* 输出的字随系统语言变,只认顺序:最后两个十六进制是接电源、用电池(前面三个是最小、最大、步长)
|
|
49
|
+
*/
|
|
50
|
+
export declare function winAcSleepSeconds(powercfg: string): number | null;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cotutor service 在 Windows 上要的几样(service.ts 接这里):
|
|
3
|
+
* 登录时起来:写用户自己的注册表 HKCU\...\Run(不要管理员)。不用计划任务:登录触发对普通令牌可能要管理员,缺省还有 3 天超时、低优先级要逐项改。
|
|
4
|
+
* 没有窗口:Run 里是 wscript.exe 跑一个 JScript 启动器,WScript.Shell.Run(命令, 0) 起 node,控制台藏着;node 的子进程跟着用这个藏着的控制台,不另弹窗。
|
|
5
|
+
* 不用 conhost --headless(2026-11-06 Windows 11 build 26300 上直接以 0 退、node 根本没起,本来也没写进文档);不用 VBScript(微软在逐步下线);不用 powershell -WindowStyle Hidden(会闪一下)。
|
|
6
|
+
* 崩了再起:看护进程 cotutor service run(service.ts 的 runKeeper,一个 node),起 serve,非 0 隔 10 秒再起,0 不起,和 launchd、systemd 同样的说法。
|
|
7
|
+
* 停:按命令行找这个 workspace 的看护进程与 serve(PowerShell,输出不随系统语言变),taskkill /T /F。
|
|
8
|
+
* 这里全是拼字符串与读输出的纯函数,真跑在 service.ts。
|
|
9
|
+
*/
|
|
10
|
+
/** 一个参数写进命令行(CommandLineToArgvW 的规矩:引号前的反斜杠翻倍再转义引号,结尾的反斜杠翻倍) */
|
|
11
|
+
export function winQuote(a) {
|
|
12
|
+
if (a && !/[\s"]/.test(a))
|
|
13
|
+
return a;
|
|
14
|
+
let out = '"';
|
|
15
|
+
let slashes = 0;
|
|
16
|
+
for (const ch of a) {
|
|
17
|
+
if (ch === '\\') {
|
|
18
|
+
slashes++;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ch === '"') {
|
|
22
|
+
out += `${'\\'.repeat(slashes * 2 + 1)}"`;
|
|
23
|
+
slashes = 0;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
out += '\\'.repeat(slashes) + ch;
|
|
27
|
+
slashes = 0;
|
|
28
|
+
}
|
|
29
|
+
return `${out}${'\\'.repeat(slashes * 2)}"`;
|
|
30
|
+
}
|
|
31
|
+
export const winCommandLine = (args) => args.map(winQuote).join(' ');
|
|
32
|
+
/** 启动器的内容:wscript 跑它,藏着窗口起 args;第二行记着 args,找服务时读回来 */
|
|
33
|
+
export function windowsLauncher(args, root) {
|
|
34
|
+
return `// cotutor service install 写的;改了会被下次 install 盖掉。卸掉:cotutor service uninstall --workspace ${root.replace(/[\r\n]/g, ' ')}
|
|
35
|
+
// args: ${JSON.stringify(args)}
|
|
36
|
+
new ActiveXObject("WScript.Shell").Run(${JSON.stringify(winCommandLine(args))}, 0, false);
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
/** 启动器存成 UTF-16 带 BOM:wscript 按这个读,路径里的中文才对(UTF-8 它按系统代码页读) */
|
|
40
|
+
export const encodeLauncher = (text) => Buffer.concat([Buffer.from([0xff, 0xfe]), Buffer.from(text, 'utf16le')]);
|
|
41
|
+
/** 读服务文件:带 UTF-16 的 BOM 就按它解,别的按 UTF-8 */
|
|
42
|
+
export function decodeServiceFile(buf) {
|
|
43
|
+
return buf[0] === 0xff && buf[1] === 0xfe ? buf.subarray(2).toString('utf16le') : buf.toString('utf8');
|
|
44
|
+
}
|
|
45
|
+
/** 从启动器里读回 args;不是启动器 → null */
|
|
46
|
+
export function launcherArgs(text) {
|
|
47
|
+
const m = /^\/\/ args: (\[.*\])\s*$/m.exec(text);
|
|
48
|
+
if (!m)
|
|
49
|
+
return null;
|
|
50
|
+
try {
|
|
51
|
+
const v = JSON.parse(m[1]);
|
|
52
|
+
return Array.isArray(v) && v.every((x) => typeof x === 'string') ? v : null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const RUN_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
|
|
59
|
+
/**
|
|
60
|
+
* 任务管理器「启动应用」里关掉一条,Run 项还在,只在这里记一笔:值的第一个字节单数 = 关了(02 开、03 关;2026-11-06 那台机器上 Docker Desktop 就是 03)。
|
|
61
|
+
* 那里显示的名字是 wscript.exe 的文件描述(Microsoft ® Windows Based Script Host),不是 Run 项的名字,看不出是 cotutor,所以要靠 service status 来说
|
|
62
|
+
*/
|
|
63
|
+
export const STARTUP_APPROVED_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run';
|
|
64
|
+
/** reg query 这个值的输出:被关掉了没有(没这个值 = 没关) */
|
|
65
|
+
export function startupDisabled(regQuery) {
|
|
66
|
+
const m = /REG_BINARY\s+([0-9a-fA-F]{2})/.exec(regQuery);
|
|
67
|
+
return m ? (Number.parseInt(m[1], 16) & 1) === 1 : false;
|
|
68
|
+
}
|
|
69
|
+
/** Run 里写的那条 */
|
|
70
|
+
export const runValue = (wscript, file) => `"${wscript}" //B //Nologo "${file}"`;
|
|
71
|
+
/** 跑一段 PowerShell 的参数:编码传进去不用管引号,输出定成 UTF-8,关掉进度(第一次用模块时它往 stderr 写一堆) */
|
|
72
|
+
export function psArgs(script) {
|
|
73
|
+
const full = `[Console]::OutputEncoding=[Text.Encoding]::UTF8\n$ProgressPreference='SilentlyContinue'\n$ErrorActionPreference='SilentlyContinue'\n${script}`;
|
|
74
|
+
return ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', Buffer.from(full, 'utf16le').toString('base64')];
|
|
75
|
+
}
|
|
76
|
+
/** 找这个 workspace 的看护进程(service run)与它起的 serve(带 --log-dir;终端里的 cotutor serve 不算) */
|
|
77
|
+
export function findProcsScript(root) {
|
|
78
|
+
return [
|
|
79
|
+
`$root = '${root.replaceAll("'", "''")}'`,
|
|
80
|
+
`$found = @(Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Where-Object { $c = $_.CommandLine; $c -and $c.Contains($root) -and ($c.Contains(' service run ') -or ($c.Contains(' serve ') -and $c.Contains('--log-dir'))) })`,
|
|
81
|
+
`ConvertTo-Json -Compress -InputObject @($found | ForEach-Object { @{ pid = $_.ProcessId; keeper = $_.CommandLine.Contains(' service run ') } })`,
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
/** 上面那段的输出;坏的、空的当没有 */
|
|
85
|
+
export function parseProcs(text) {
|
|
86
|
+
let raw;
|
|
87
|
+
try {
|
|
88
|
+
raw = JSON.parse(text.trim() || '[]');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const list = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
94
|
+
return list.flatMap((x) => {
|
|
95
|
+
const o = x;
|
|
96
|
+
return typeof o.pid === 'number' ? [{ pid: o.pid, keeper: o.keeper === true }] : [];
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 拦着闲置睡眠(同 macOS 的 caffeinate -i):SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED) 之后等 serve 退出。
|
|
101
|
+
* 状态跟着这个线程走:进程被杀或 serve 没了就撤掉
|
|
102
|
+
*/
|
|
103
|
+
export function awakeScript(pid) {
|
|
104
|
+
return [
|
|
105
|
+
`$t = Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint f);' -Name Awake -Namespace Cotutor -PassThru`,
|
|
106
|
+
'[void]$t::SetThreadExecutionState([uint32]2147483649)',
|
|
107
|
+
`Wait-Process -Id ${pid}`,
|
|
108
|
+
].join('\n');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* powercfg /query SCHEME_CURRENT SUB_SLEEP STANDBYIDLE:接着电源几秒没人碰就睡(0 = 不睡);读不出 → null。
|
|
112
|
+
* 输出的字随系统语言变,只认顺序:最后两个十六进制是接电源、用电池(前面三个是最小、最大、步长)
|
|
113
|
+
*/
|
|
114
|
+
export function winAcSleepSeconds(powercfg) {
|
|
115
|
+
const hex = [...powercfg.matchAll(/0x([0-9a-fA-F]{8})/g)].map((m) => Number.parseInt(m[1], 16));
|
|
116
|
+
return hex.length >= 2 ? hex[hex.length - 2] : null;
|
|
117
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export type ServicePlatform = 'darwin' | 'linux' | 'win32';
|
|
2
|
+
/** 跑命令、读写文件之外要的:系统、家目录、uid;run 测试换假的 */
|
|
3
|
+
export interface ServiceHost {
|
|
4
|
+
platform: NodeJS.Platform;
|
|
5
|
+
home: string;
|
|
6
|
+
uid: number;
|
|
7
|
+
env: NodeJS.ProcessEnv;
|
|
8
|
+
run(cmd: string, args: string[]): Promise<{
|
|
9
|
+
code: number;
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export declare const realHost: () => ServiceHost;
|
|
15
|
+
/** 这个系统做没做 */
|
|
16
|
+
export declare function servicePlatform(platform: NodeJS.Platform): ServicePlatform;
|
|
17
|
+
type HostPaths = Pick<ServiceHost, 'platform' | 'home' | 'env'>;
|
|
18
|
+
/** 服务名:workspace 目录名的小写字母数字连字符;撞了别的 workspace 加路径的短 hash */
|
|
19
|
+
export declare function serviceName(root: string, taken?: boolean): string;
|
|
20
|
+
/** 服务文件放哪 */
|
|
21
|
+
export declare function serviceDir(host: HostPaths): string;
|
|
22
|
+
/** 日志放哪(一个服务一个目录) */
|
|
23
|
+
export declare function serviceLogDir(host: HostPaths, name: string): string;
|
|
24
|
+
/** serve 起来之前的输出(node 自己报的、模块没加载上)去哪:给人看的一句 */
|
|
25
|
+
export declare function earlyLogHint(platform: ServicePlatform, s: {
|
|
26
|
+
label: string;
|
|
27
|
+
logDir: string | null;
|
|
28
|
+
}): string;
|
|
29
|
+
/** 看护进程的日志(Windows):serve 退了几次、起来之前的输出 */
|
|
30
|
+
export declare const KEEPER_LOG = "keeper.log";
|
|
31
|
+
/**
|
|
32
|
+
* 看护进程(Windows;cotutor service run):起 serve,非 0 隔 10 秒再起,0 不起(端口被占着);同 launchd 的 KeepAlive、systemd 的 Restart=on-failure。
|
|
33
|
+
* 给 serve 带上 COTUTOR_SERVICE(mode 算后台服务、端口被占以 0 退);返回退出码
|
|
34
|
+
*/
|
|
35
|
+
export declare function runKeeper(o: {
|
|
36
|
+
root: string;
|
|
37
|
+
logDir: string;
|
|
38
|
+
label: string;
|
|
39
|
+
node?: string;
|
|
40
|
+
bin?: string;
|
|
41
|
+
restartMs?: number;
|
|
42
|
+
}): Promise<number>;
|
|
43
|
+
export declare const wscriptPath: (host: ServiceHost) => string;
|
|
44
|
+
export interface ServiceSpec {
|
|
45
|
+
name: string;
|
|
46
|
+
/** launchd 的 Label / systemd 的单元名(不带 .service) */
|
|
47
|
+
label: string;
|
|
48
|
+
/** 跑什么:node、bin、serve 与它的旗标 */
|
|
49
|
+
args: string[];
|
|
50
|
+
root: string;
|
|
51
|
+
logDir: string;
|
|
52
|
+
path: string;
|
|
53
|
+
}
|
|
54
|
+
export declare const xml: (s: string) => string;
|
|
55
|
+
/** macOS 的 LaunchAgent */
|
|
56
|
+
export declare function launchdPlist(s: ServiceSpec): string;
|
|
57
|
+
/** Linux 的 systemd 用户服务 */
|
|
58
|
+
export declare function systemdUnit(s: ServiceSpec): string;
|
|
59
|
+
/** 从服务文件里读回跑的参数(找它是哪个 workspace 的) */
|
|
60
|
+
export declare function serviceArgs(text: string): string[];
|
|
61
|
+
export interface InstalledService {
|
|
62
|
+
name: string;
|
|
63
|
+
label: string;
|
|
64
|
+
file: string;
|
|
65
|
+
args: string[];
|
|
66
|
+
root: string;
|
|
67
|
+
logDir: string | null;
|
|
68
|
+
}
|
|
69
|
+
/** 这台电脑上 cotutor 装的服务(各是哪个 workspace 的) */
|
|
70
|
+
export declare function listServices(host: ServiceHost): Promise<InstalledService[]>;
|
|
71
|
+
/** 这个 workspace 的服务;没装 → null(Windows 上路径不分大小写) */
|
|
72
|
+
export declare function findService(host: ServiceHost, root: string): Promise<InstalledService | null>;
|
|
73
|
+
/** cotutor 的 bin(npm 装的是 dist/app/cli → 包根;仓里直跑是 src/app/cli → 仓根,一样往上三层) */
|
|
74
|
+
export declare const binPath: () => string;
|
|
75
|
+
/** 装:写服务文件、交给 launchd / systemd 起来;已经装过就照现在的 node、bin、PATH 重写一遍再起 */
|
|
76
|
+
export declare function installService(host: ServiceHost, root: string, opts?: {
|
|
77
|
+
node?: string;
|
|
78
|
+
bin?: string;
|
|
79
|
+
}): Promise<{
|
|
80
|
+
spec: ServiceSpec;
|
|
81
|
+
file: string;
|
|
82
|
+
replaced: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
/** 卸:停下、删服务文件;日志留着 */
|
|
85
|
+
export declare function uninstallService(host: ServiceHost, root: string): Promise<InstalledService | null>;
|
|
86
|
+
/** 起 / 停 / 重起。macOS 的停是从 launchd 卸下、Windows 的停是杀进程(服务文件都还在,下次登录又会起;要一直不起用 uninstall) */
|
|
87
|
+
export declare function controlService(host: ServiceHost, root: string, what: 'start' | 'stop' | 'restart'): Promise<InstalledService>;
|
|
88
|
+
/** launchctl print 那一大段里要的几行(一层缩进的 state / pid / last exit code) */
|
|
89
|
+
export declare function parseLaunchctlPrint(text: string): {
|
|
90
|
+
running: boolean;
|
|
91
|
+
pid: number | null;
|
|
92
|
+
lastExit: string | null;
|
|
93
|
+
};
|
|
94
|
+
/** systemctl show -p ActiveState,MainPID,ExecMainStatus 的输出 */
|
|
95
|
+
export declare function parseSystemctlShow(text: string): {
|
|
96
|
+
running: boolean;
|
|
97
|
+
pid: number | null;
|
|
98
|
+
lastExit: string | null;
|
|
99
|
+
};
|
|
100
|
+
/** /api/health 回的(只取要的) */
|
|
101
|
+
export interface Health {
|
|
102
|
+
version: string | null;
|
|
103
|
+
started: string;
|
|
104
|
+
pid?: number;
|
|
105
|
+
mode?: string;
|
|
106
|
+
vault?: string;
|
|
107
|
+
/** 现在开着几通电话(托盘:退出前要不要问一声) */
|
|
108
|
+
calls?: number;
|
|
109
|
+
/** 百炼配了没有(托盘:没配算有事要处理) */
|
|
110
|
+
bailian?: boolean;
|
|
111
|
+
configError?: string | null;
|
|
112
|
+
/** 问到的是 https 还是 http(这边加的,不是服务回的) */
|
|
113
|
+
scheme?: 'https' | 'http';
|
|
114
|
+
}
|
|
115
|
+
/** 本机问一下 serve 起来没有(自签证书不验);先 https 再 http */
|
|
116
|
+
export declare function probeHealth(port: number, timeoutMs?: number): Promise<Health | null>;
|
|
117
|
+
export interface ServiceStatus {
|
|
118
|
+
installed: InstalledService | null;
|
|
119
|
+
running: boolean;
|
|
120
|
+
pid: number | null;
|
|
121
|
+
lastExit: string | null;
|
|
122
|
+
health: Health | null;
|
|
123
|
+
logFile: string | null;
|
|
124
|
+
/** Windows:下次登录还会不会自己起来(Run 项被删了、任务管理器里关掉了都算不会);别的系统 null */
|
|
125
|
+
autostart: boolean | null;
|
|
126
|
+
}
|
|
127
|
+
/** 装没装、在不在跑、问得到不(端口来自 cotutor.json 或 --port) */
|
|
128
|
+
export declare function serviceStatus(host: ServiceHost, root: string, port: number): Promise<ServiceStatus>;
|
|
129
|
+
/** 起来以后等它答应(装完、重起完);等不到 → null */
|
|
130
|
+
export declare function waitHealthy(port: number, ms?: number, since?: string): Promise<Health | null>;
|
|
131
|
+
/** 日志的最后 n 行(今天的没有就找最近一天的) */
|
|
132
|
+
export declare function tailLog(logDir: string, n?: number): Promise<{
|
|
133
|
+
file: string;
|
|
134
|
+
lines: string[];
|
|
135
|
+
} | null>;
|
|
136
|
+
/** pmset -g custom 里「AC Power:」那一段的 sleep(接着电源几分钟没人碰就睡,0 = 不睡);没有那一段 → null */
|
|
137
|
+
export declare function acSleepMinutes(pmset: string): number | null;
|
|
138
|
+
export {};
|