cotutor 0.4.3 → 0.4.5
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/CHANGELOG.md +47 -0
- package/INSTALL.md +159 -0
- package/README.md +64 -17
- package/dist/app/cli/activities.d.ts +1 -1
- package/dist/app/cli/activities.js +2 -2
- package/dist/app/cli/cert.js +2 -1
- package/dist/app/cli/chalk/main.d.ts +0 -1
- package/dist/app/cli/chalk/main.js +8 -12
- package/dist/app/cli/commands.d.ts +50 -0
- package/dist/app/cli/commands.js +353 -0
- package/dist/app/cli/doctor.js +32 -17
- package/dist/app/cli/guide.d.ts +6 -0
- package/dist/app/cli/guide.js +17 -0
- package/dist/app/cli/init.d.ts +2 -0
- package/dist/app/cli/init.js +60 -6
- package/dist/app/cli/main.js +109 -46
- package/dist/app/cli/migrate.js +1 -1
- package/dist/app/cli/port.js +2 -10
- package/dist/app/cli/root-ca.d.ts +8 -0
- package/dist/app/cli/root-ca.js +33 -0
- package/dist/app/cli/sandbox.js +2 -7
- package/dist/app/cli/serve.d.ts +11 -2
- package/dist/app/cli/serve.js +49 -3
- package/dist/app/cli/service.d.ts +4 -1
- package/dist/app/cli/service.js +5 -2
- package/dist/app/cli/shipped.js +1 -1
- package/dist/app/cli/skeleton.d.ts +2 -0
- package/dist/app/cli/skeleton.js +3 -2
- package/dist/app/cli/skills.js +2 -2
- package/dist/app/cli/themes.js +2 -2
- package/dist/app/cli/tray.d.ts +6 -1
- package/dist/app/cli/tray.js +8 -5
- package/dist/app/cli/tutors.d.ts +2 -2
- package/dist/app/cli/tutors.js +4 -4
- package/dist/app/cli/update-cmd.js +4 -4
- package/dist/app/cli/usage.d.ts +26 -2
- package/dist/app/cli/usage.js +167 -38
- package/dist/app/http/access.js +1 -1
- package/dist/app/http/app.js +5 -1
- package/dist/app/http/parent-home.js +5 -0
- package/dist/app/http/stage.js +2 -2
- package/dist/app/mock/mock.js +3 -0
- package/dist/app/skills/analyze-doc.js +4 -8
- package/dist/app/skills/home-doc.js +3 -7
- package/dist/app/skills/tune-doc.js +4 -8
- package/dist/app/workspace.d.ts +16 -3
- package/dist/app/workspace.js +31 -9
- package/dist/runtime/home/home.js +1 -1
- package/dist/runtime/runner.js +2 -2
- package/dist/shared/home.d.ts +2 -0
- package/dist/shared/home.js +9 -0
- package/dist/stage/fonts/Assistant/Assistant-Bold.woff2 +0 -0
- package/dist/stage/fonts/Assistant/Assistant-Medium.woff2 +0 -0
- package/dist/stage/fonts/Assistant/Assistant-Regular.woff2 +0 -0
- package/dist/stage/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
- package/dist/stage/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
- package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
- package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
- package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
- package/dist/stage/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
- package/dist/stage/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
- package/dist/stage/fonts/Liberation/LiberationSans-Regular.woff2 +0 -0
- package/dist/stage/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
- package/dist/stage/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
- package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
- package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
- package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
- package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
- package/dist/stage/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
- package/dist/stage/fonts/Virgil/Virgil-Regular.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2 +0 -0
- package/dist/stage/fonts/Xiaolai/Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2 +0 -0
- package/dist/ui/dev/dev-page.js +5 -5
- package/dist/ui/kid/kid-page.js +2 -0
- package/dist/ui/kid/offline-sw.d.ts +1 -0
- package/dist/ui/kid/offline-sw.js +42 -0
- package/dist/ui/parent/parent-home-page.js +9 -6
- package/install.ps1 +67 -0
- package/install.sh +84 -0
- package/package.json +15 -10
- package/skills/cotutor-analyze/SKILL.md +1 -1
- package/skills/cotutor-analyze/references//345/221/275/344/273/244/344/270/216/346/226/207/344/273/266.md +168 -10
- package/skills/cotutor-home/SKILL.md +1 -1
- package/skills/cotutor-home/references//345/221/275/344/273/244.md +75 -7
- package/skills/cotutor-tune/SKILL.md +8 -8
- package/skills/cotutor-tune/references//345/255/227/346/256/265.md +164 -10
- package/skills/cotutor-tutor/SKILL.md +1 -1
package/dist/ui/dev/dev-page.js
CHANGED
|
@@ -1297,7 +1297,7 @@ ${pageDomJs(4000)}
|
|
|
1297
1297
|
catch (e) { feedback(card, false, e.message); }
|
|
1298
1298
|
} } }, '补上'))));
|
|
1299
1299
|
card.append(h('ul', { class: 'gaps' }, ...gaps.map((g) => h('li', {}, h('span', { class: g.kind === 'retired' ? 'plus minus' : 'plus' }, g.kind === 'retired' ? '−' : '+'), h('span', {}, g.detail)))));
|
|
1300
|
-
card.append(h('p', { class: 'hint' }, '新版 cotutor 带来的新老师、新运行时、命令模板里的新旗标(+),和新版不再读的出厂段(−)。cotutor.json 是你的政策文件,机器不会自己改它,所以要你点一下。只改上面这些,你改过的值一个都不动;终端里等同于 cotutor
|
|
1300
|
+
card.append(h('p', { class: 'hint' }, '新版 cotutor 带来的新老师、新运行时、命令模板里的新旗标(+),和新版不再读的出厂段(−)。cotutor.json 是你的政策文件,机器不会自己改它,所以要你点一下。只改上面这些,你改过的值一个都不动;终端里等同于 cotutor refresh --config。'));
|
|
1301
1301
|
return card;
|
|
1302
1302
|
};
|
|
1303
1303
|
|
|
@@ -1590,7 +1590,7 @@ ${pageDomJs(4000)}
|
|
|
1590
1590
|
const rows = listRows();
|
|
1591
1591
|
const first = (want && rows.find((r) => (isTutorFile(r) ? r.tutor : r.tutor + '/' + r.name) === want)) || rows[0];
|
|
1592
1592
|
if (first) return openActivity(first.tutor, first.name, true, first.kind);
|
|
1593
|
-
$('#activity').replaceChildren(h('div', { class: 'wrap act-wrap' }, actHead(), h('p', { class: 'note' }, '这个 workspace 里还没有 activity(agents/<老师>/activities/<名>.md);cotutor
|
|
1593
|
+
$('#activity').replaceChildren(h('div', { class: 'wrap act-wrap' }, actHead(), h('p', { class: 'note' }, '这个 workspace 里还没有 activity(agents/<老师>/activities/<名>.md);cotutor refresh 会补上出厂的。')));
|
|
1594
1594
|
};
|
|
1595
1595
|
|
|
1596
1596
|
const openActivity = async (t, n, force, kind) => {
|
|
@@ -1875,7 +1875,7 @@ ${pageDomJs(4000)}
|
|
|
1875
1875
|
if (!r.diff) return [h('p', { class: 'note' }, tf ? '自家加的老师,没有出厂那份可比。' : '自家加的 activity,没有出厂那份可比。')];
|
|
1876
1876
|
const out = [h('div', { class: 'srow' }, r.diff.length ? h('span', { class: 'st accent' }, '和出厂不一样 ' + r.diff.length + ' 处') : h('span', { class: 'st ok' }, '和出厂一样'), h('span', { class: 'note' }, '含没存的')),
|
|
1877
1877
|
...r.diff.map((d) => hunkEl(d, true))];
|
|
1878
|
-
out.push(h('p', { class: 'note' }, c.state === 'upgradable' ? '这份没改过,是旧版出厂的;cotutor
|
|
1878
|
+
out.push(h('p', { class: 'note' }, c.state === 'upgradable' ? '这份没改过,是旧版出厂的;cotutor refresh 会换成新的。' : c.state === 'latest' ? '存下以后就算改过的出厂件:cotutor refresh 不再自动换新版,只报 diff。' : '改过的出厂件,cotutor refresh 不再自动换新版,只报 diff。'));
|
|
1879
1879
|
out.push(rule(), h('div', { class: 'srow' },
|
|
1880
1880
|
h('button', { class: 'btn danger', type: 'button', disabled: !r.diff.length && !dirtyCount(), on: { click: restoreActivityBtn } }, '恢复出厂'),
|
|
1881
1881
|
h('span', { class: 'note' }, c.state === 'latest' ? '磁盘上那份就是出厂的,恢复只是丢掉没存的改动。' : '换回出厂那份;你这份存成 ' + bakName(c) + '。' + (tf ? '别的老师、这位老师的 activity 都不碰。' : '别的 activity 不碰。'))));
|
|
@@ -1920,7 +1920,7 @@ ${pageDomJs(4000)}
|
|
|
1920
1920
|
out.push(h('div', { class: 'srow' }, h('span', { class: 'note', style: 'flex:1;min-width:160px' }, '这就是新话题里老师的系统提示:老师文件去掉 frontmatter' + (pv.board ? ',后面再接板书写法' : '') + '。'), h('button', { class: 'btn small', type: 'button', on: { click: (e) => copy(pv.text, e.target) } }, '复制全文')));
|
|
1921
1921
|
if (pv.rules) {
|
|
1922
1922
|
out.push(rule(), h('h3', {}, '话题第一条还带守则'),
|
|
1923
|
-
h('p', { class: 'note' }, '有脸的老师共用的 ' + pv.rules.path + ',机器件,cotutor
|
|
1923
|
+
h('p', { class: 'note' }, '有脸的老师共用的 ' + pv.rules.path + ',机器件,cotutor refresh 每次覆盖,这里不改。这位老师要不一样的做法,写进上面的老师文件,它优先。'),
|
|
1924
1924
|
h('details', {}, h('summary', {}, '看守则原文'), h('pre', { class: 'pv tool' }, pv.rules.text)));
|
|
1925
1925
|
}
|
|
1926
1926
|
out.push(rule(), h('p', { class: 'note' }, '档案、日记、计划这些每轮现拼进上下文包,不在这里;看一轮会拼成什么(不花钱):'),
|
|
@@ -1965,7 +1965,7 @@ ${pageDomJs(4000)}
|
|
|
1965
1965
|
const restoreActivityBtn = async () => {
|
|
1966
1966
|
const c = act.cur;
|
|
1967
1967
|
const tf = isTutorFile(c);
|
|
1968
|
-
const lead = c.state === 'latest' ? '磁盘上那份就是出厂的;没存的 ' + dirtyCount() + ' 处丢掉。' : '你这份存成 ' + bakName(c) + (dirtyCount() ? ',没存的 ' + dirtyCount() + ' 处一起丢掉' : '') + '。和 cotutor
|
|
1968
|
+
const lead = c.state === 'latest' ? '磁盘上那份就是出厂的;没存的 ' + dirtyCount() + ' 处丢掉。' : '你这份存成 ' + bakName(c) + (dirtyCount() ? ',没存的 ' + dirtyCount() + ' 处一起丢掉' : '') + '。和 cotutor reset ' + c.tutor + (tf ? '' : '/' + c.name) + ' 同一条路,' + (tf ? '别的老师不碰。' : '别的 activity 不碰。');
|
|
1969
1969
|
if (!(await ask('换回出厂那份?', [lead], '恢复出厂', '算了'))) return;
|
|
1970
1970
|
let r;
|
|
1971
1971
|
try { r = await api('POST', docUrl(c) + '/restore', {}); } catch (e) { alert(e.message); return; }
|
package/dist/ui/kid/kid-page.js
CHANGED
|
@@ -3674,6 +3674,8 @@ __REEL_DOCK_JS__
|
|
|
3674
3674
|
location.reload();
|
|
3675
3675
|
};
|
|
3676
3676
|
setInterval(() => { staleReload(); if (S.tutor) { if (!S.pending) loadDay(true); } else loadHome(); }, 5000);
|
|
3677
|
+
// 离线页(offline-sw.ts):电脑关了、睡着了时,点开主屏幕图标看到「老师们还没到」,不是浏览器的报错。只在 https(或 localhost)上有;回放、预览里不装
|
|
3678
|
+
if (!REEL && !PREVIEW && window.isSecureContext && 'serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js').catch(() => {});
|
|
3677
3679
|
document.addEventListener('visibilitychange', () => { if (!document.hidden) (S.tutor ? loadDay(true) : loadHome()); });
|
|
3678
3680
|
// 孩子端刷新(手动的、Safari 自己重载的)回到手上这位老师;在首页刷新就回首页。只读回放不记(重载回来是今天的)
|
|
3679
3681
|
if (!REEL && !PREVIEW) window.addEventListener('pagehide', () => { try { if (S.tutor && !S.readonly) sessionStorage.setItem('kid-resume', S.tutor.name); else sessionStorage.removeItem('kid-resume'); } catch {} });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const KID_SW_JS: string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 孩子端的离线页(Service Worker,GET /sw.js):电脑关了、睡着了、服务没在跑时,平板上打开孩子端看到的不是浏览器的报错,是「老师们休息中」。
|
|
3
|
+
* 和页面开着时断线的样子(kid-page 的 #rest)同一句:都是「电脑那边连不上」;「老师们还没到」是百炼没配好,另一回事。
|
|
4
|
+
* 孩子端永远没有错误:这一页只说老师们休息、叫爸爸妈妈,不说连接、不说服务器。
|
|
5
|
+
* 页面开着时断线由页面自己管(灰掉、「老师们休息中」);这一页只在重新打开(iPad 把网页 App 清出内存后再点开、刷新)时出现。
|
|
6
|
+
*
|
|
7
|
+
* 只接管孩子端那几页的打开(导航);接口、静态文件、别的页面一律不碰。不缓存任何东西:平时原样走网络,孩子看不到旧页面;
|
|
8
|
+
* 连不上或 12 秒没回应才给离线页,它每 5 秒问一次 /api/health,通了就自己刷新回去。
|
|
9
|
+
* Service Worker 只在安全上下文里有(https 且平板信任了根证书,或 localhost);http 时孩子端照旧,什么都不变。
|
|
10
|
+
* 改了这个文件就改 VERSION:平板上的旧 worker 靠脚本内容变了才换。
|
|
11
|
+
*/
|
|
12
|
+
const VERSION = '2';
|
|
13
|
+
/** 离线页本身:没有网可取,样式、脚本都内联 */
|
|
14
|
+
const OFFLINE_HTML = [
|
|
15
|
+
'<!doctype html><html lang="zh-CN"><head><meta charset="utf-8">',
|
|
16
|
+
'<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">',
|
|
17
|
+
'<meta name="apple-mobile-web-app-capable" content="yes"><title>老师们休息中</title>',
|
|
18
|
+
'<style>html,body{height:100%;margin:0}body{display:flex;align-items:center;justify-content:center;background:#f7f3ea;color:#3a352c;',
|
|
19
|
+
'font:22px/1.6 -apple-system,"PingFang SC","Microsoft YaHei",sans-serif;text-align:center;-webkit-user-select:none;user-select:none}',
|
|
20
|
+
'p{margin:0 24px}small{display:block;margin-top:12px;font-size:17px;color:#8a8273}</style></head>',
|
|
21
|
+
'<body><p id="off">老师们休息中<small>叫爸爸妈妈来看一下:家里那台电脑是不是关了、睡着了</small></p>',
|
|
22
|
+
'<script>setInterval(function(){fetch("/api/health",{cache:"no-store"}).then(function(r){if(r.ok)location.reload()}).catch(function(){})},5000)</script>',
|
|
23
|
+
'</body></html>',
|
|
24
|
+
].join('');
|
|
25
|
+
export const KID_SW_JS = `// cotutor 孩子端的离线页 v${VERSION}(src/ui/kid/offline-sw.ts)
|
|
26
|
+
const KID = new Set(['/', '/dictation', '/dictation/', '/talk', '/talk/']);
|
|
27
|
+
const WAIT_MS = 12000;
|
|
28
|
+
const OFFLINE = ${JSON.stringify(OFFLINE_HTML)};
|
|
29
|
+
self.addEventListener('install', () => { self.skipWaiting(); });
|
|
30
|
+
self.addEventListener('activate', (e) => { e.waitUntil(self.clients.claim()); });
|
|
31
|
+
self.addEventListener('fetch', (e) => {
|
|
32
|
+
const r = e.request;
|
|
33
|
+
if (r.mode !== 'navigate' || r.method !== 'GET') return;
|
|
34
|
+
const u = new URL(r.url);
|
|
35
|
+
if (u.origin !== self.location.origin || !KID.has(u.pathname)) return;
|
|
36
|
+
const offline = () => new Response(OFFLINE, { status: 200, headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' } });
|
|
37
|
+
e.respondWith(Promise.race([
|
|
38
|
+
fetch(r).catch(() => null),
|
|
39
|
+
new Promise((resolve) => { setTimeout(() => resolve(null), WAIT_MS); }),
|
|
40
|
+
]).then((res) => res || offline()));
|
|
41
|
+
});
|
|
42
|
+
`;
|
|
@@ -337,7 +337,7 @@ ${pageDomJs(3200)}
|
|
|
337
337
|
if (st.ready) rows.push(h('div', { class: 'it' }, h('span', { class: 'tx' }, h('b', {}, '配好了'), h('small', {}, (st.keyTail ? 'key …' + st.keyTail + ' · 业务空间 ' + st.workspaceId : '测试用的假百炼'))),
|
|
338
338
|
h('button', { type: 'button', class: 'x', disabled: BL.busy || null, on: { click: blTest } }, BL.busy && !BL.open ? '在试…' : '试连'),
|
|
339
339
|
st.canEdit ? h('button', { type: 'button', class: 'x', on: { click: () => { BL.open = !BL.open; BL.msg = ''; blDraw(); } } }, BL.open ? '收起' : '换一把') : null));
|
|
340
|
-
else rows.push(h('div', { class: 'box' }, h('b', {}, '还没配,孩子那边打不开'), h('div', { class: 'note', style: 'padding:0' }, '老师开口和想讲稿都走百炼,要百炼「按量付费」的 API key(控制台「密钥管理」里创建)和业务空间 id(控制台的业务空间详情里看);Token Plan 的 sk-sp-
|
|
340
|
+
else rows.push(h('div', { class: 'box' }, h('b', {}, '还没配,孩子那边打不开'), h('div', { class: 'note', style: 'padding:0' }, '老师开口和想讲稿都走百炼,要百炼「按量付费」的 API key(控制台「密钥管理」里创建)和业务空间 id(控制台的业务空间详情里看);Token Plan 的 sk-sp- 不行。存在这台电脑上,不进孩子的 cotutor 文件夹。')));
|
|
341
341
|
if (!st.ready || BL.open) {
|
|
342
342
|
if (!st.canEdit) rows.push(h('div', { class: 'box' }, h('div', { class: 'note', style: 'padding:0' }, '先设家长密码:在电脑上跑 cotutor pin;或者在这台电脑上打开家长端来配。')));
|
|
343
343
|
else rows.push(h('div', { class: 'box' }, h('label', { class: 'lbl', for: 'bl-key' }, 'API key'), blKey, h('label', { class: 'lbl', for: 'bl-ws' }, '业务空间 id'), blWs,
|
|
@@ -365,24 +365,27 @@ ${pageDomJs(3200)}
|
|
|
365
365
|
h('span', { style: 'flex:none;display:flex', html: QR_ICON }), h('span', { class: 'tx' }, h('b', {}, '扫码打开'), h('small', {}, seen)), h('span', { class: 'lnk', style: 'font-size:14px' }, '展开'))));
|
|
366
366
|
return;
|
|
367
367
|
}
|
|
368
|
-
|
|
368
|
+
if (QR.to === 'ca' && !d.ca) QR.to = 'kid';
|
|
369
|
+
const kid = QR.to === 'kid', ca = QR.to === 'ca', c = kid ? d : ca ? d.ca : (d.parent || d);
|
|
369
370
|
const useIp = QR.ip && c.ip;
|
|
370
|
-
|
|
371
|
+
// 装证书(serve.ts 的 http 那一面给根证书):平板第一次用之前扫一次;有证书、找得到根证书才有这一格
|
|
372
|
+
const tabs = [['kid', '孩子的平板'], ['parent', '我的手机']].concat(d.ca ? [['ca', '装证书']] : []);
|
|
373
|
+
const seg = h('div', { class: 'seg', role: 'group', 'aria-label': '给谁扫' }, ...tabs.map(([k, l]) =>
|
|
371
374
|
h('button', { type: 'button', class: QR.to === k ? 'on' : '', 'aria-pressed': QR.to === k ? 'true' : 'false', on: { click: () => { QR.to = k; qrDraw(); } } }, l)));
|
|
372
375
|
const print = '/parent/qr?' + new URLSearchParams(Object.assign({}, useIp ? { via: 'ip' } : {}, kid ? {} : { to: 'parent' })).toString();
|
|
373
376
|
qrEl.replaceChildren(
|
|
374
377
|
h('div', { class: 'gh' }, h('span', {}, '扫码打开'), h('button', { type: 'button', class: 'x', 'aria-expanded': 'true', on: { click: () => qrToggle(false) } }, '收起')),
|
|
375
378
|
h('div', { class: 'grp' }, h('div', { class: 'box' }, seg,
|
|
376
379
|
h('div', { class: 'qrrow' }, h('div', { class: 'qrimg', html: (useIp ? c.svgIp : c.svg) || '' }),
|
|
377
|
-
h('b', { style: 'font-weight:600' }, kid ? '用孩子平板的相机扫一下' : '用你自己的手机扫一下'),
|
|
378
|
-
h('span', { class: 'lbl', style: 'line-height:1.5' }, kid ? '打开的就是孩子的首页。在 Safari 里「添加到主屏幕」,以后点图标就进来。' : '打开的是家长端:看记录、排首页。也可以添加到主屏幕。')),
|
|
380
|
+
h('b', { style: 'font-weight:600' }, kid ? '用孩子平板的相机扫一下' : ca ? '平板第一次用:先扫这张装证书' : '用你自己的手机扫一下'),
|
|
381
|
+
h('span', { class: 'lbl', style: 'line-height:1.5' }, kid ? '打开的就是孩子的首页。在 Safari 里「添加到主屏幕」,以后点图标就进来。' : ca ? '扫了点「允许」下载描述文件;到「设置」最上面点「已下载描述文件」装上;再到「设置 › 通用 › 关于本机 › 证书信任设置」把开关打开。装好再扫「孩子的平板」那张。每台平板做一次。' : '打开的是家长端:看记录、排首页。也可以添加到主屏幕。')),
|
|
379
382
|
h('div', { class: 'qrurl' }, useIp ? c.ip : c.url),
|
|
380
383
|
d.https ? null : h('div', { class: 'qrwarn' }, d.notes[0] || ''),
|
|
381
384
|
h('div', { class: 'row2', style: 'font-size:14px' },
|
|
382
385
|
c.ip ? h('button', { type: 'button', class: 'x', style: 'height:auto;padding:0;font-size:14px;text-align:left', on: { click: () => { QR.ip = !QR.ip; qrDraw(); } } }, useIp ? '换回 ' + host(c.url) : '扫了打不开?换成 ' + host(c.ip)) : h('span'),
|
|
383
386
|
h('span', { style: 'display:flex;gap:14px;flex:none' },
|
|
384
387
|
h('a', { class: 'lnk kidl', style: 'font-size:14px', href: '/', target: '_blank' }, '孩子端 ↗'),
|
|
385
|
-
h('a', { class: 'lnk', style: 'font-size:14px', href: print, target: '_blank' }, '打印 ›'))))),
|
|
388
|
+
ca ? null : h('a', { class: 'lnk', style: 'font-size:14px', href: print, target: '_blank' }, '打印 ›'))))),
|
|
386
389
|
h('div', { class: 'note' }, d.https ? (d.notes[0] || '') : '', d.devices ? '' : (d.https ? ' ' : '') + '还没有平板连进来过,所以这块先开着;连过以后自动收起。'));
|
|
387
390
|
};
|
|
388
391
|
|
package/install.ps1
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# cotutor 一行安装(Windows,在 PowerShell 里粘贴):
|
|
2
|
+
# & ([scriptblock]::Create([Text.Encoding]::UTF8.GetString((iwr -useb https://cdn.jsdelivr.net/npm/cotutor@latest/install.ps1).Content)))
|
|
3
|
+
# (jsDelivr 不标编码,PowerShell 5.1 的 irm 会把中文按 Latin-1 读成乱码,所以自己按 UTF-8 解)
|
|
4
|
+
# 连不上 jsDelivr 就从 GitHub 取(GitHub 标了 utf-8,irm 就行):
|
|
5
|
+
# irm https://raw.githubusercontent.com/TarsLab/cotutor/main/install.ps1 | iex
|
|
6
|
+
# 顺手建好孩子的文件夹、装好后台服务(短名 称呼 年级),最后接上就行:
|
|
7
|
+
# & ([scriptblock]::Create([Text.Encoding]::UTF8.GetString((iwr -useb https://cdn.jsdelivr.net/npm/cotutor@latest/install.ps1).Content))) ming 小明 2
|
|
8
|
+
#
|
|
9
|
+
# 只做这几件事:查 Node 的版本;npm 连不上就用国内镜像;装 cotutor。
|
|
10
|
+
# 不要管理员,不改执行策略:npm、cotutor 都用 .cmd 跑(PowerShell 缺省策略会拦 .ps1)。Node 没装或太旧时只说怎么装,不替你装。
|
|
11
|
+
$ErrorActionPreference = 'Stop'
|
|
12
|
+
|
|
13
|
+
function Say($text) { Write-Host $text }
|
|
14
|
+
function Stop-Here($text) { Write-Host $text; throw 'cotutor-install-stopped' }
|
|
15
|
+
|
|
16
|
+
$needMajor = 22
|
|
17
|
+
$needMinor = 18
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
# ---- 1. Node ----
|
|
21
|
+
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
|
|
22
|
+
Stop-Here "这台电脑还没有 Node.js:到 https://nodejs.org 下载 LTS 版(Windows 安装程序)装上,或者跑 winget install OpenJS.NodeJS.LTS;装完重开 PowerShell 再跑这一行。"
|
|
23
|
+
}
|
|
24
|
+
$v = (& node -p 'process.versions.node').Trim()
|
|
25
|
+
$parts = $v.Split('.')
|
|
26
|
+
if ([int]$parts[0] -lt $needMajor -or ([int]$parts[0] -eq $needMajor -and [int]$parts[1] -lt $needMinor)) {
|
|
27
|
+
Stop-Here "Node.js 是 $v,cotutor 要 $needMajor.$needMinor 以上:到 https://nodejs.org 装新的 LTS 版,重开 PowerShell 再跑这一行。"
|
|
28
|
+
}
|
|
29
|
+
if (-not (Get-Command npm.cmd -ErrorAction SilentlyContinue)) { Stop-Here '有 Node.js 但找不到 npm:到 https://nodejs.org 重新装一次 LTS 版。' }
|
|
30
|
+
Say "Node.js $v"
|
|
31
|
+
|
|
32
|
+
# ---- 2. npm 连得上吗(国内常连不上,换镜像) ----
|
|
33
|
+
$registry = $null
|
|
34
|
+
try { Invoke-WebRequest -UseBasicParsing -TimeoutSec 8 'https://registry.npmjs.org/cotutor/latest' | Out-Null }
|
|
35
|
+
catch { $registry = 'https://registry.npmmirror.com'; Say "npm 连不上或太慢,用国内镜像 $registry" }
|
|
36
|
+
|
|
37
|
+
# ---- 3. 装 ----
|
|
38
|
+
Say '正在下载 cotutor,要一会儿……'
|
|
39
|
+
$npmArgs = @('i', '-g', 'cotutor', '--no-audit', '--no-fund')
|
|
40
|
+
if ($registry) { $npmArgs += "--registry=$registry" }
|
|
41
|
+
& npm.cmd @npmArgs
|
|
42
|
+
if ($LASTEXITCODE -ne 0) { Stop-Here 'npm 没装成:看上面的报错;连不上就过一会儿再试。' }
|
|
43
|
+
# 刚装上的 cotutor.cmd 在 npm 的全局目录里;这个窗口的 PATH 可能还没有它
|
|
44
|
+
$globalDir = (& npm.cmd prefix -g).Trim()
|
|
45
|
+
if (-not (Get-Command cotutor.cmd -ErrorAction SilentlyContinue)) { $env:Path = "$globalDir;$env:Path" }
|
|
46
|
+
if (-not (Get-Command cotutor.cmd -ErrorAction SilentlyContinue)) { Stop-Here "装好了但找不到 cotutor:重开 PowerShell 再试;还不行,把 $globalDir 加进 PATH。" }
|
|
47
|
+
Say ('cotutor ' + (& cotutor.cmd --version).Trim() + ' 装好了')
|
|
48
|
+
|
|
49
|
+
# ---- 4. 带了孩子的信息就接着建文件夹、装后台服务 ----
|
|
50
|
+
if ($args.Count -ge 1) {
|
|
51
|
+
$initArgs = @('init', $args[0])
|
|
52
|
+
if ($args.Count -ge 2 -and $args[1]) { $initArgs += @('--name', $args[1]) }
|
|
53
|
+
if ($args.Count -ge 3 -and $args[2]) { $initArgs += @('--grade', [string]$args[2]) }
|
|
54
|
+
& cotutor.cmd @initArgs
|
|
55
|
+
if ($LASTEXITCODE -ne 0) { Stop-Here '建孩子的文件夹没成:看上面的报错。' }
|
|
56
|
+
& cotutor.cmd service install
|
|
57
|
+
Say ''
|
|
58
|
+
Say '好了。家长端已经在浏览器里打开;以后点任务栏右下角 ^ 里的 cotutor 图标,或者跑 cotutor.cmd open。'
|
|
59
|
+
} else {
|
|
60
|
+
Say ''
|
|
61
|
+
Say '接下来(短名用小写字母,不用真名;年级 1 到 6):'
|
|
62
|
+
Say ' cotutor.cmd init ming --name 小明 --grade 2'
|
|
63
|
+
Say ' cotutor.cmd service install'
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
if ($_.Exception.Message -ne 'cotutor-install-stopped') { Write-Host ('出错了:' + $_.Exception.Message) }
|
|
67
|
+
}
|
package/install.sh
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# cotutor 一行安装(macOS、Linux):
|
|
3
|
+
# curl -fsSL https://cdn.jsdelivr.net/npm/cotutor@latest/install.sh | sh
|
|
4
|
+
# 连不上 jsDelivr 就从 GitHub 取:
|
|
5
|
+
# curl -fsSL https://raw.githubusercontent.com/TarsLab/cotutor/main/install.sh | sh
|
|
6
|
+
# 顺手建好孩子的文件夹、装好后台服务(短名 称呼 年级):
|
|
7
|
+
# curl -fsSL https://cdn.jsdelivr.net/npm/cotutor@latest/install.sh | sh -s -- ming 小明 2
|
|
8
|
+
#
|
|
9
|
+
# 只做这几件事:查 Node 的版本;npm 连不上就用国内镜像;全局目录写不了就换到自己家目录下(不用 sudo);装 cotutor。
|
|
10
|
+
# 不用 sudo,不改系统设置。Node 没装或太旧时只说怎么装,不替你装。
|
|
11
|
+
set -eu
|
|
12
|
+
|
|
13
|
+
say() { printf '%s\n' "$*"; }
|
|
14
|
+
die() { say "$*"; exit 1; }
|
|
15
|
+
|
|
16
|
+
NEED_MAJOR=22
|
|
17
|
+
NEED_MINOR=18
|
|
18
|
+
|
|
19
|
+
# ---- 1. Node ----
|
|
20
|
+
command -v node >/dev/null 2>&1 || die "这台电脑还没有 Node.js:到 https://nodejs.org 下载 LTS 版装上,重开终端再跑这一行。"
|
|
21
|
+
v=$(node -p 'process.versions.node')
|
|
22
|
+
major=${v%%.*}
|
|
23
|
+
rest=${v#*.}
|
|
24
|
+
minor=${rest%%.*}
|
|
25
|
+
if [ "$major" -lt "$NEED_MAJOR" ] || { [ "$major" -eq "$NEED_MAJOR" ] && [ "$minor" -lt "$NEED_MINOR" ]; }; then
|
|
26
|
+
die "Node.js 是 $v,cotutor 要 $NEED_MAJOR.$NEED_MINOR 以上:到 https://nodejs.org 装新的 LTS 版,重开终端再跑这一行。"
|
|
27
|
+
fi
|
|
28
|
+
command -v npm >/dev/null 2>&1 || die "有 Node.js 但找不到 npm:到 https://nodejs.org 重新装一次 LTS 版。"
|
|
29
|
+
say "Node.js $v"
|
|
30
|
+
|
|
31
|
+
# ---- 2. npm 连得上吗(国内常连不上,换镜像) ----
|
|
32
|
+
REGISTRY=""
|
|
33
|
+
if ! curl -fsS -o /dev/null --max-time 8 https://registry.npmjs.org/cotutor/latest 2>/dev/null; then
|
|
34
|
+
REGISTRY="https://registry.npmmirror.com"
|
|
35
|
+
say "npm 连不上或太慢,用国内镜像 $REGISTRY"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# ---- 3. 全局目录写得了吗(官网的 Mac 安装包装在 /usr/local,要 sudo 才能写;不用 sudo,换到家目录下) ----
|
|
39
|
+
root=$(npm root -g)
|
|
40
|
+
target=$root
|
|
41
|
+
[ -d "$target" ] || target=$(dirname "$target")
|
|
42
|
+
if [ ! -w "$target" ]; then
|
|
43
|
+
prefix="$HOME/.npm-global"
|
|
44
|
+
say "npm 的全局目录 $root 这个账户写不了,改装到 $prefix(不用 sudo)"
|
|
45
|
+
mkdir -p "$prefix"
|
|
46
|
+
npm config set prefix "$prefix"
|
|
47
|
+
case "${SHELL:-}" in
|
|
48
|
+
*/zsh) rc="$HOME/.zshrc" ;;
|
|
49
|
+
*/bash) if [ "$(uname)" = Darwin ]; then rc="$HOME/.bash_profile"; else rc="$HOME/.bashrc"; fi ;;
|
|
50
|
+
*) rc="$HOME/.profile" ;;
|
|
51
|
+
esac
|
|
52
|
+
line='export PATH="$HOME/.npm-global/bin:$PATH"'
|
|
53
|
+
if ! grep -qsF "$line" "$rc"; then
|
|
54
|
+
printf '\n# cotutor 安装脚本加的:npm 全局命令装在家目录下\n%s\n' "$line" >> "$rc"
|
|
55
|
+
say "在 $rc 里加了一行 PATH,新开的终端就认得 cotutor"
|
|
56
|
+
fi
|
|
57
|
+
PATH="$prefix/bin:$PATH"
|
|
58
|
+
export PATH
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# ---- 4. 装 ----
|
|
62
|
+
say "正在下载 cotutor,要一会儿……"
|
|
63
|
+
if [ -n "$REGISTRY" ]; then npm i -g cotutor --no-audit --no-fund --registry="$REGISTRY"; else npm i -g cotutor --no-audit --no-fund; fi
|
|
64
|
+
command -v cotutor >/dev/null 2>&1 || die "装好了但找不到 cotutor 命令:重开终端再试;还不行,把 $(npm prefix -g)/bin 加进 PATH。"
|
|
65
|
+
say "cotutor $(cotutor --version) 装好了"
|
|
66
|
+
|
|
67
|
+
# ---- 5. 带了孩子的信息就接着建文件夹、装后台服务 ----
|
|
68
|
+
if [ $# -ge 1 ]; then
|
|
69
|
+
slug=$1
|
|
70
|
+
set -- "$@" "" ""
|
|
71
|
+
name=$2
|
|
72
|
+
grade=$3
|
|
73
|
+
if [ -n "$name" ] && [ -n "$grade" ]; then cotutor init "$slug" --name "$name" --grade "$grade"
|
|
74
|
+
elif [ -n "$name" ]; then cotutor init "$slug" --name "$name"
|
|
75
|
+
else cotutor init "$slug"; fi
|
|
76
|
+
cotutor service install
|
|
77
|
+
say ""
|
|
78
|
+
say "好了。家长端已经在浏览器里打开;以后点菜单栏的 cotutor 图标,或在终端跑 cotutor open。"
|
|
79
|
+
else
|
|
80
|
+
say ""
|
|
81
|
+
say "接下来(短名用小写字母,不用真名;年级 1 到 6):"
|
|
82
|
+
say " cotutor init ming --name 小明 --grade 2"
|
|
83
|
+
say " cotutor service install"
|
|
84
|
+
fi
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cotutor",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"releaseNotes": [
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
5
|
+
"让 AI 助手帮你装更省事:不用输网址,对它说「帮我在这台电脑上装 cotutor,先跑 npx cotutor@latest guide,照它说的一步步做」",
|
|
6
|
+
"孩子的笔记文件夹(档案、日记、老师的记忆)新装时放在 cotutor 文件夹旁边,也可以用你已有的 Obsidian 库;以前装的照旧能用",
|
|
7
|
+
"Linux 上的后台服务能起来了",
|
|
8
|
+
"命令更好懂:cotutor --help 只列命令,每条的用法和例子在它自己的帮助里;写错的选项会直接说哪里不对,不再悄悄忽略",
|
|
9
|
+
"换新出厂文件改叫 cotutor refresh,把改过的老师换回出厂的用 cotutor reset;升级还是 cotutor update"
|
|
9
10
|
],
|
|
10
11
|
"description": "AI tutors that co-teach with parents at home: real-time voice, an interactive whiteboard, and learning memory in your own Obsidian vault. Self-hosted; built for China's elementary curriculum.",
|
|
11
12
|
"type": "module",
|
|
@@ -58,8 +59,12 @@
|
|
|
58
59
|
"cards",
|
|
59
60
|
"skills",
|
|
60
61
|
"README.md",
|
|
62
|
+
"INSTALL.md",
|
|
61
63
|
"LICENSE",
|
|
62
|
-
"NOTICE"
|
|
64
|
+
"NOTICE",
|
|
65
|
+
"install.sh",
|
|
66
|
+
"install.ps1",
|
|
67
|
+
"CHANGELOG.md"
|
|
63
68
|
],
|
|
64
69
|
"scripts": {
|
|
65
70
|
"gen:skills": "node --experimental-strip-types scripts/gen-skills.ts",
|
|
@@ -75,18 +80,18 @@
|
|
|
75
80
|
},
|
|
76
81
|
"dependencies": {
|
|
77
82
|
"@ai-sdk/alibaba": "2.0.78",
|
|
78
|
-
"@excalidraw/excalidraw": "0.18.1",
|
|
79
83
|
"ai": "7.0.155",
|
|
80
84
|
"hanzi-writer-data": "2.0.1",
|
|
81
|
-
"react": "^18.3.1",
|
|
82
|
-
"react-dom": "^18.3.1",
|
|
83
85
|
"typescript": "^5.6.0",
|
|
84
86
|
"zod": "^4.4.3"
|
|
85
87
|
},
|
|
86
88
|
"devDependencies": {
|
|
89
|
+
"@excalidraw/excalidraw": "0.18.1",
|
|
87
90
|
"@types/node": "^22.20.1",
|
|
88
91
|
"@types/react": "^18.3.31",
|
|
89
92
|
"@types/react-dom": "^18.3.7",
|
|
90
|
-
"esbuild": "^0.28.2"
|
|
93
|
+
"esbuild": "^0.28.2",
|
|
94
|
+
"react": "^18.3.1",
|
|
95
|
+
"react-dom": "^18.3.1"
|
|
91
96
|
}
|
|
92
97
|
}
|
|
@@ -5,7 +5,7 @@ description: 在 cotutor workspace 里分析 AI 老师的对话:某一轮传了
|
|
|
5
5
|
|
|
6
6
|
<!-- 给人看
|
|
7
7
|
谁读:家长在 workspace 根开的编程助手
|
|
8
|
-
能改:机器件,
|
|
8
|
+
能改:机器件,refresh 覆盖;references/命令与文件.md 由 src/app/skills/analyze-doc.ts 生成
|
|
9
9
|
改了:在试用 workspace 里开编程助手问一句「老师为什么…」(《写提示词.md》§一)
|
|
10
10
|
-->
|
|
11
11
|
|
|
@@ -1,17 +1,175 @@
|
|
|
1
1
|
# 命令与文件(机器生成,别改)
|
|
2
2
|
|
|
3
|
-
## 分析用的命令(在 workspace
|
|
3
|
+
## 分析用的命令(在 workspace 根跑;每条就是 cotutor <命令> --help 的内容)
|
|
4
4
|
|
|
5
5
|
```
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cotutor show <老师> <job> [<日期>] [--
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
这些命令都认 --workspace <目录>(在 workspace 根跑可以不写)和 --sandbox(在试用副本里跑,不进孩子的记录)。
|
|
7
|
+
|
|
8
|
+
cotutor show — 看一轮:问了什么、上下文包、讲稿与卡、读了什么
|
|
9
|
+
|
|
10
|
+
用法:
|
|
11
|
+
cotutor show <老师> <job> [<日期>] [--evals] [--json]
|
|
12
|
+
|
|
13
|
+
选项:
|
|
14
|
+
--evals 看回放的那轮(evals/ 里的)
|
|
15
|
+
--json 机器可读的输出
|
|
16
|
+
|
|
17
|
+
说明:
|
|
18
|
+
- 日期缺省今天;--json 和家长端「看原文」是同一份
|
|
19
|
+
|
|
20
|
+
例子:
|
|
21
|
+
cotutor show math-tutor 1620-1 2026-09-12 --json
|
|
22
|
+
|
|
23
|
+
cotutor pack — 干跑上下文包:不起模型,看老师会拿到什么
|
|
24
|
+
|
|
25
|
+
用法:
|
|
26
|
+
cotutor pack <老师> [<消息>] [--activity <名> [--param '名=值;名=值']] [--from kid|system] [--at <ISO时间>] [--json]
|
|
27
|
+
|
|
28
|
+
选项:
|
|
29
|
+
--activity <名> 像孩子点了首页的 activity 按钮,新开话题
|
|
30
|
+
--param '名=值;名=值' activity 的参数(按钮下面那几行)
|
|
31
|
+
--from kid|system 谁说的(缺省 kid;system 不算孩子说的)
|
|
32
|
+
--at <ISO时间> 当作这个时间
|
|
33
|
+
--json 机器可读的输出
|
|
34
|
+
|
|
35
|
+
说明:
|
|
36
|
+
- 每段来自哪个文件、一共几条、按政策带了几条;改了档案、日记、计划立刻看效果
|
|
37
|
+
|
|
38
|
+
例子:
|
|
39
|
+
cotutor pack math-tutor "讲讲退位"
|
|
40
|
+
|
|
41
|
+
cotutor replay — 同一问按现在的提示词再跑一遍,并排对照
|
|
42
|
+
|
|
43
|
+
用法:
|
|
44
|
+
cotutor replay <老师> <job> [<日期>] [--runtime <名>] [--json]
|
|
45
|
+
|
|
46
|
+
选项:
|
|
47
|
+
--runtime <名> 换个运行时
|
|
48
|
+
--json 机器可读的输出
|
|
49
|
+
|
|
50
|
+
说明:
|
|
51
|
+
- 落 evals/,不进孩子的对话、不配音
|
|
52
|
+
|
|
53
|
+
注意:
|
|
54
|
+
- 花钱
|
|
55
|
+
|
|
56
|
+
例子:
|
|
57
|
+
cotutor replay math-tutor 1620-1 2026-09-12
|
|
58
|
+
|
|
59
|
+
cotutor compare — 再看一次回放的对照
|
|
60
|
+
|
|
61
|
+
用法:
|
|
62
|
+
cotutor compare <老师> [<evalJob>] [<日期>] [--json]
|
|
63
|
+
|
|
64
|
+
选项:
|
|
65
|
+
--json 机器可读的输出
|
|
66
|
+
|
|
67
|
+
说明:
|
|
68
|
+
- 不给 evalJob 就列这天回放过哪些
|
|
69
|
+
|
|
70
|
+
例子:
|
|
71
|
+
cotutor compare math-tutor
|
|
72
|
+
|
|
73
|
+
cotutor trace — 回放一轮的事件
|
|
74
|
+
|
|
75
|
+
用法:
|
|
76
|
+
cotutor trace <老师> <job> [<日期>] [--lane <道>] [--json]
|
|
77
|
+
|
|
78
|
+
选项:
|
|
79
|
+
--lane <道> 只看这几道的事件,逗号分开,如 main,tts
|
|
80
|
+
--json 机器可读的输出
|
|
81
|
+
|
|
82
|
+
说明:
|
|
83
|
+
- 读 <日期>.<job>.events.jsonl;日期缺省今天
|
|
84
|
+
|
|
85
|
+
例子:
|
|
86
|
+
cotutor trace math-tutor 1620-1 --lane main
|
|
87
|
+
|
|
88
|
+
cotutor doctor — 体检;--fix 修掉能自动修的
|
|
89
|
+
|
|
90
|
+
用法:
|
|
91
|
+
cotutor doctor [--json]
|
|
92
|
+
cotutor doctor --fix
|
|
93
|
+
cotutor doctor --live
|
|
94
|
+
|
|
95
|
+
选项:
|
|
96
|
+
--fix 修掉能自动修的(幂等,不碰孩子的数据,不用人输东西),要人来的留着
|
|
97
|
+
--live 真连一次百炼的嘴、真配一句音
|
|
98
|
+
--json 机器可读的输出
|
|
99
|
+
|
|
100
|
+
说明:
|
|
101
|
+
- --json 里没过的项带 cmd(能直接跑)或 human(要人来)
|
|
102
|
+
- 有必需项没过,退出码 1
|
|
103
|
+
|
|
104
|
+
注意:
|
|
105
|
+
- --live 花一分钱
|
|
106
|
+
|
|
107
|
+
例子:
|
|
108
|
+
cotutor doctor --fix
|
|
109
|
+
cotutor doctor --json
|
|
110
|
+
|
|
111
|
+
cotutor send — 终端里给老师发一条
|
|
112
|
+
|
|
113
|
+
用法:
|
|
114
|
+
cotutor send <老师> [<消息>] [--new] [--photo <图,图>] [--quiet] [--json]
|
|
115
|
+
cotutor send <老师> --activity <名> [--param '名=值;名=值']
|
|
116
|
+
|
|
117
|
+
选项:
|
|
118
|
+
--new 开新话题
|
|
119
|
+
--photo <图,图> 带作业照片(jpg / png,最多 9 张);有照片时消息可以空
|
|
120
|
+
--activity <名> 像孩子点了首页的 activity 按钮,新开话题
|
|
121
|
+
--param '名=值;名=值' activity 的参数(按钮下面那几行)
|
|
122
|
+
--from kid|system 谁说的(缺省 kid;system 不算孩子说的)
|
|
123
|
+
--runtime <名> 换个运行时
|
|
124
|
+
--lane <道> 只看这几道的事件,逗号分开,如 main,tts
|
|
125
|
+
--quiet 只要结果,不打印过程
|
|
126
|
+
--json 机器可读的输出
|
|
127
|
+
|
|
128
|
+
说明:
|
|
129
|
+
- 孩子的话照实时写(同孩子端),只是没有嘴;事件落 events.jsonl,事后 cotutor trace 看
|
|
130
|
+
|
|
131
|
+
注意:
|
|
132
|
+
- 花钱
|
|
133
|
+
- 写进孩子的对话记录(试一下用 --sandbox)
|
|
134
|
+
|
|
135
|
+
例子:
|
|
136
|
+
cotutor send math-tutor "这一步为什么要借位"
|
|
137
|
+
|
|
138
|
+
cotutor rate — 给一个话题打星(1–5)
|
|
139
|
+
|
|
140
|
+
用法:
|
|
141
|
+
cotutor rate <老师> <话题> <1-5> [--date <日期>] [--json]
|
|
142
|
+
|
|
143
|
+
选项:
|
|
144
|
+
--date <日期> 哪天(YYYY-MM-DD,缺省今天)
|
|
145
|
+
--json 机器可读的输出
|
|
146
|
+
|
|
147
|
+
说明:
|
|
148
|
+
- 和家长端同一条路;到 vault.keepScore 星的话题,记账时摘要才进日记
|
|
149
|
+
|
|
150
|
+
例子:
|
|
151
|
+
cotutor rate math-tutor 1620-1 4
|
|
152
|
+
|
|
153
|
+
cotutor bookkeep — 记账:把这天的话题写进日记
|
|
154
|
+
|
|
155
|
+
用法:
|
|
156
|
+
cotutor bookkeep <老师> [--date <日期>] [--thread <话题>] [--quiet] [--json]
|
|
157
|
+
|
|
158
|
+
选项:
|
|
159
|
+
--date <日期> 哪天(YYYY-MM-DD,缺省今天)
|
|
160
|
+
--thread <话题> 只记这个话题
|
|
161
|
+
--quiet 不打印过程
|
|
162
|
+
--json 机器可读的输出
|
|
163
|
+
|
|
164
|
+
说明:
|
|
165
|
+
- 每个还没记过的话题起一轮记账,应用写进笔记文件夹的日记
|
|
166
|
+
|
|
167
|
+
注意:
|
|
168
|
+
- 花钱
|
|
169
|
+
- 写孩子的笔记文件夹
|
|
170
|
+
|
|
171
|
+
例子:
|
|
172
|
+
cotutor bookkeep math-tutor
|
|
15
173
|
```
|
|
16
174
|
|
|
17
175
|
## 一轮的文件(conversations/ 下;回放的在 evals/ 下,同一套名字)
|
|
@@ -5,7 +5,7 @@ description: 排 cotutor 孩子端的首页。孩子学完之后,家长在 works
|
|
|
5
5
|
|
|
6
6
|
<!-- 给人看
|
|
7
7
|
谁读:家长在 workspace 根开的编程助手
|
|
8
|
-
能改:机器件,
|
|
8
|
+
能改:机器件,refresh 覆盖;references/ 下的首页语法.md、命令.md、tutor.md 由 src/app/skills/home-doc.ts 与 cards/tutor/card.md 生成
|
|
9
9
|
改了:在试用 workspace 里开编程助手说一句「总结一下今天」(《写提示词.md》§一)
|
|
10
10
|
-->
|
|
11
11
|
|