@mcptoolshop/pianoai 1.0.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.

Potentially problematic release.


This version of @mcptoolshop/pianoai might be problematic. Click here for more details.

Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.es.md +253 -0
  3. package/README.fr.md +253 -0
  4. package/README.hi.md +253 -0
  5. package/README.it.md +253 -0
  6. package/README.ja.md +253 -0
  7. package/README.md +253 -0
  8. package/README.pt-BR.md +253 -0
  9. package/README.zh.md +253 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +294 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/index.d.ts +10 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +21 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/mcp-server.d.ts +3 -0
  19. package/dist/mcp-server.d.ts.map +1 -0
  20. package/dist/mcp-server.js +324 -0
  21. package/dist/mcp-server.js.map +1 -0
  22. package/dist/note-parser.d.ts +69 -0
  23. package/dist/note-parser.d.ts.map +1 -0
  24. package/dist/note-parser.js +172 -0
  25. package/dist/note-parser.js.map +1 -0
  26. package/dist/session.d.ts +101 -0
  27. package/dist/session.d.ts.map +1 -0
  28. package/dist/session.js +339 -0
  29. package/dist/session.js.map +1 -0
  30. package/dist/smoke.d.ts +2 -0
  31. package/dist/smoke.d.ts.map +1 -0
  32. package/dist/smoke.js +207 -0
  33. package/dist/smoke.js.map +1 -0
  34. package/dist/teaching.d.ts +106 -0
  35. package/dist/teaching.d.ts.map +1 -0
  36. package/dist/teaching.js +269 -0
  37. package/dist/teaching.js.map +1 -0
  38. package/dist/types.d.ts +206 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +22 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/vmpk.d.ts +21 -0
  43. package/dist/vmpk.d.ts.map +1 -0
  44. package/dist/vmpk.js +185 -0
  45. package/dist/vmpk.js.map +1 -0
  46. package/logo.svg +10 -0
  47. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mcp-tool-shop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.es.md ADDED
@@ -0,0 +1,253 @@
1
+ <p align="center">
2
+ <a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <strong>Español</strong> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="logo.svg" alt="PianoAI logo" width="180" />
7
+ </p>
8
+
9
+ <h1 align="center">PianoAI</h1>
10
+
11
+ <p align="center">
12
+ Servidor MCP + CLI para enseñanza de piano con IA — reproduce a través de VMPK vía MIDI con retroalimentación por voz.
13
+ </p>
14
+
15
+ [![Tests](https://img.shields.io/badge/tests-121_passing-brightgreen)](https://github.com/mcp-tool-shop-org/pianoai)
16
+ [![Smoke](https://img.shields.io/badge/smoke-20_passing-brightgreen)](https://github.com/mcp-tool-shop-org/pianoai)
17
+ [![MCP Tools](https://img.shields.io/badge/MCP_tools-7-purple)](https://github.com/mcp-tool-shop-org/pianoai)
18
+ [![Songs](https://img.shields.io/badge/songs-10_(via_ai--music--sheets)-blue)](https://github.com/mcp-tool-shop-org/ai-music-sheets)
19
+
20
+ ## ¿Qué es esto?
21
+
22
+ Un CLI en TypeScript y servidor MCP que carga canciones de piano desde [ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets), las convierte a MIDI y las reproduce a través de [VMPK](https://vmpk.sourceforge.io/) mediante un puerto MIDI virtual. El motor de enseñanza lanza interjecciones en los límites de compás y en momentos clave, permitiendo que un LLM actúe como profesor de piano en vivo con retroalimentación por voz y notificaciones aparte.
23
+
24
+ ## Características
25
+
26
+ - **4 modos de reproducción** — completa, compás por compás, manos separadas, bucle
27
+ - **Control de velocidad** — práctica lenta a 0.5x hasta reproducción rápida a 2x, acumulable con modificación de tempo
28
+ - **Seguimiento de progreso** — callbacks configurables en hitos porcentuales o por compás
29
+ - **7 hooks de enseñanza** — console, silent, recording, callback, voice, aside, compose
30
+ - **Retroalimentación por voz** — salida `VoiceDirective` para integración con mcp-voice-soundboard
31
+ - **Interjecciones aparte** — salida `AsideDirective` para la bandeja de mcp-aside
32
+ - **Análisis seguro** — las notas incorrectas se omiten con `ParseWarning`s recopilados
33
+ - **7 herramientas MCP** — exponen el registro, notas de enseñanza y recomendaciones de canciones a LLMs
34
+ - **Analizador de notas** — notación científica de altura a MIDI y viceversa
35
+ - **Conector simulado** — cobertura completa de tests sin hardware MIDI
36
+
37
+ ## Requisitos previos
38
+
39
+ 1. **[loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)** — crea un puerto MIDI virtual (ej. "loopMIDI Port")
40
+ 2. **[VMPK](https://vmpk.sourceforge.io/)** — configura la entrada MIDI a tu puerto loopMIDI
41
+ 3. **Node.js 18+**
42
+
43
+ ## Instalación
44
+
45
+ ```bash
46
+ npm install -g @mcptoolshop/pianoai
47
+ ```
48
+
49
+ ## Inicio rápido
50
+
51
+ ```bash
52
+ # Listar todas las canciones
53
+ pianai list
54
+
55
+ # Mostrar detalles de canción + notas de enseñanza
56
+ pianai info moonlight-sonata-mvt1
57
+
58
+ # Reproducir una canción a través de VMPK
59
+ pianai play let-it-be
60
+
61
+ # Reproducir con modificación de tempo
62
+ pianai play basic-12-bar-blues --tempo 80
63
+
64
+ # Avanzar compás por compás
65
+ pianai play autumn-leaves --mode measure
66
+
67
+ # Práctica a mitad de velocidad
68
+ pianai play moonlight-sonata-mvt1 --speed 0.5
69
+
70
+ # Práctica lenta con manos separadas
71
+ pianai play dream-on --speed 0.75 --mode hands
72
+ ```
73
+
74
+ ## Servidor MCP
75
+
76
+ El servidor MCP expone 7 herramientas para integración con LLMs:
77
+
78
+ | Herramienta | Descripción |
79
+ |-------------|-------------|
80
+ | `list_songs` | Explorar/buscar canciones por género, dificultad o consulta |
81
+ | `song_info` | Obtener lenguaje musical completo, objetivos de enseñanza, sugerencias de práctica |
82
+ | `registry_stats` | Conteo de canciones por género y dificultad |
83
+ | `teaching_note` | Nota de enseñanza por compás, digitación, dinámicas |
84
+ | `suggest_song` | Obtener una recomendación basada en criterios |
85
+ | `list_measures` | Vista general de compases con notas de enseñanza + advertencias de análisis |
86
+ | `practice_setup` | Sugerir velocidad, modo y configuración de voz para una canción |
87
+
88
+ ```bash
89
+ # Iniciar el servidor MCP (transporte stdio)
90
+ pnpm mcp
91
+ ```
92
+
93
+ ### Configuración de Claude Desktop
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "pianai": {
99
+ "command": "pianai-mcp"
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## Comandos del CLI
106
+
107
+ | Comando | Descripción |
108
+ |---------|-------------|
109
+ | `list [--genre <genre>]` | Listar canciones disponibles, opcionalmente filtradas por género |
110
+ | `info <song-id>` | Mostrar detalles de canción: lenguaje musical, notas de enseñanza, estructura |
111
+ | `play <song-id> [opts]` | Reproducir una canción a través de VMPK vía MIDI |
112
+ | `stats` | Estadísticas del registro (canciones, géneros, compases) |
113
+ | `ports` | Listar puertos de salida MIDI disponibles |
114
+ | `help` | Mostrar información de uso |
115
+
116
+ ### Opciones de reproducción
117
+
118
+ | Bandera | Descripción |
119
+ |---------|-------------|
120
+ | `--port <name>` | Nombre del puerto MIDI (por defecto: autodetectar loopMIDI) |
121
+ | `--tempo <bpm>` | Modificar el tempo predeterminado de la canción (10-400 BPM) |
122
+ | `--speed <mult>` | Multiplicador de velocidad: 0.5 = mitad, 1.0 = normal, 2.0 = doble |
123
+ | `--mode <mode>` | Modo de reproducción: `full`, `measure`, `hands`, `loop` |
124
+
125
+ ## Motor de enseñanza
126
+
127
+ El motor de enseñanza dispara hooks durante la reproducción. 7 implementaciones de hooks cubren todos los casos de uso:
128
+
129
+ | Hook | Caso de uso |
130
+ |------|-------------|
131
+ | `createConsoleTeachingHook()` | CLI — registra compases, momentos y finalización en consola |
132
+ | `createSilentTeachingHook()` | Testing — sin operación |
133
+ | `createRecordingTeachingHook()` | Testing — graba eventos para aserciones |
134
+ | `createCallbackTeachingHook(cb)` | Personalizado — redirige a cualquier callback asíncrono |
135
+ | `createVoiceTeachingHook(sink)` | Voz — produce `VoiceDirective` para mcp-voice-soundboard |
136
+ | `createAsideTeachingHook(sink)` | Aparte — produce `AsideDirective` para la bandeja de mcp-aside |
137
+ | `composeTeachingHooks(...hooks)` | Múltiple — despacha a múltiples hooks en serie |
138
+
139
+ ### Retroalimentación por voz
140
+
141
+ ```typescript
142
+ import { createSession, createVoiceTeachingHook } from "@mcptoolshop/pianoai";
143
+ import { getSong } from "ai-music-sheets";
144
+
145
+ const voiceHook = createVoiceTeachingHook(
146
+ async (directive) => {
147
+ // Redirigir a voice_speak de mcp-voice-soundboard
148
+ console.log(`[Voice] ${directive.text}`);
149
+ },
150
+ { voice: "narrator", speechSpeed: 0.9 }
151
+ );
152
+
153
+ const session = createSession(getSong("moonlight-sonata-mvt1")!, connector, {
154
+ teachingHook: voiceHook,
155
+ speed: 0.5, // práctica a mitad de velocidad
156
+ });
157
+
158
+ await session.play();
159
+ // voiceHook.directives → todas las instrucciones de voz que se dispararon
160
+ ```
161
+
162
+ ### Composición de hooks
163
+
164
+ ```typescript
165
+ import {
166
+ createVoiceTeachingHook,
167
+ createAsideTeachingHook,
168
+ createRecordingTeachingHook,
169
+ composeTeachingHooks,
170
+ } from "@mcptoolshop/pianoai";
171
+
172
+ // Los tres se disparan en cada evento
173
+ const composed = composeTeachingHooks(
174
+ createVoiceTeachingHook(voiceSink),
175
+ createAsideTeachingHook(asideSink),
176
+ createRecordingTeachingHook()
177
+ );
178
+ ```
179
+
180
+ ## API programática
181
+
182
+ ```typescript
183
+ import { getSong } from "ai-music-sheets";
184
+ import { createSession, createVmpkConnector } from "@mcptoolshop/pianoai";
185
+
186
+ const connector = createVmpkConnector({ portName: /loop/i });
187
+ await connector.connect();
188
+
189
+ const song = getSong("autumn-leaves")!;
190
+ const session = createSession(song, connector, {
191
+ mode: "measure",
192
+ tempo: 100,
193
+ speed: 0.75, // 75% de velocidad para práctica
194
+ onProgress: (p) => console.log(p.percent), // "25%", "50%", etc.
195
+ });
196
+
197
+ await session.play(); // reproduce un compás, pausa
198
+ session.next(); // avanza al siguiente compás
199
+ await session.play(); // reproduce el siguiente compás
200
+ session.setSpeed(1.0); // vuelve a velocidad normal
201
+ await session.play(); // reproduce el siguiente compás a velocidad completa
202
+ session.stop(); // detiene y reinicia
203
+
204
+ // Verificar advertencias de análisis (notas incorrectas en los datos de la canción)
205
+ if (session.parseWarnings.length > 0) {
206
+ console.warn("Algunas notas no pudieron ser analizadas:", session.parseWarnings);
207
+ }
208
+
209
+ await connector.disconnect();
210
+ ```
211
+
212
+ ## Arquitectura
213
+
214
+ ```
215
+ ai-music-sheets (biblioteca) pianai (tiempo de ejecución)
216
+ ┌──────────────────────┐ ┌────────────────────────────────┐
217
+ │ SongEntry (híbrido) │────────→│ Note Parser (seguro + estricto)│
218
+ │ Registry (búsqueda) │ │ Session Engine (veloc.+progreso│
219
+ │ 10 canciones, 10 gén.│ │ Teaching Engine (7 hooks) │
220
+ └──────────────────────┘ │ VMPK Connector (JZZ) │
221
+ │ MCP Server (7 herramientas) │
222
+ │ CLI (barra de progreso + voz) │
223
+ └─────────┬──────────────────────┘
224
+ │ MIDI
225
+
226
+ ┌─────────────────┐
227
+ │ loopMIDI → VMPK │
228
+ └─────────────────┘
229
+
230
+ Enrutamiento de hooks de enseñanza:
231
+ Session → TeachingHook → VoiceDirective → mcp-voice-soundboard
232
+ → AsideDirective → bandeja de mcp-aside
233
+ → Console log → terminal del CLI
234
+ → Recording → aserciones de test
235
+ ```
236
+
237
+ ## Testing
238
+
239
+ ```bash
240
+ pnpm test # 121 tests con Vitest (parser + session + teaching + voice + aside)
241
+ pnpm smoke # 20 smoke tests (integración, sin MIDI necesario)
242
+ pnpm typecheck # tsc --noEmit
243
+ ```
244
+
245
+ El conector VMPK simulado (`createMockVmpkConnector`) registra todos los eventos MIDI sin hardware, permitiendo cobertura completa de tests. Las funciones de análisis seguro (`safeParseMeasure`) recopilan objetos `ParseWarning` en lugar de lanzar excepciones, de modo que la reproducción continúa correctamente si una canción tiene notas malformadas.
246
+
247
+ ## Relacionados
248
+
249
+ - **[ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets)** — La biblioteca de canciones: 10 géneros, formato híbrido (metadatos + lenguaje musical + compases listos para código)
250
+
251
+ ## Licencia
252
+
253
+ MIT
package/README.fr.md ADDED
@@ -0,0 +1,253 @@
1
+ <p align="center">
2
+ <a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <strong>Français</strong> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="logo.svg" alt="PianoAI logo" width="180" />
7
+ </p>
8
+
9
+ <h1 align="center">PianoAI</h1>
10
+
11
+ <p align="center">
12
+ Serveur MCP + CLI pour l'enseignement du piano par IA — joue via VMPK par MIDI avec retour vocal.
13
+ </p>
14
+
15
+ [![Tests](https://img.shields.io/badge/tests-121_passing-brightgreen)](https://github.com/mcp-tool-shop-org/pianoai)
16
+ [![Smoke](https://img.shields.io/badge/smoke-20_passing-brightgreen)](https://github.com/mcp-tool-shop-org/pianoai)
17
+ [![MCP Tools](https://img.shields.io/badge/MCP_tools-7-purple)](https://github.com/mcp-tool-shop-org/pianoai)
18
+ [![Songs](https://img.shields.io/badge/songs-10_(via_ai--music--sheets)-blue)](https://github.com/mcp-tool-shop-org/ai-music-sheets)
19
+
20
+ ## Qu'est-ce que c'est ?
21
+
22
+ Un CLI TypeScript et un serveur MCP qui charge des morceaux de piano depuis [ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets), les convertit en MIDI et les joue via [VMPK](https://vmpk.sourceforge.io/) par un port MIDI virtuel. Le moteur pédagogique lance des interjections aux limites de mesure et aux moments clés, permettant à un LLM d'agir comme un professeur de piano en direct avec retour vocal et notifications aside.
23
+
24
+ ## Fonctionnalités
25
+
26
+ - **4 modes de lecture** — complet, mesure par mesure, mains séparées, boucle
27
+ - **Contrôle de la vitesse** — 0.5x pour la pratique lente jusqu'à 2x en lecture rapide, cumulable avec le tempo personnalisé
28
+ - **Suivi de progression** — callbacks configurables par pourcentage ou par mesure
29
+ - **7 hooks pédagogiques** — console, silencieux, enregistrement, callback, voix, aside, composition
30
+ - **Retour vocal** — sortie `VoiceDirective` pour l'intégration mcp-voice-soundboard
31
+ - **Interjections aside** — sortie `AsideDirective` pour la boîte de réception mcp-aside
32
+ - **Analyse sécurisée** — les notes invalides sont ignorées avec collecte de `ParseWarning`
33
+ - **7 outils MCP** — exposent le registre, les notes pédagogiques et les recommandations de morceaux aux LLMs
34
+ - **Analyseur de notes** — notation scientifique des hauteurs vers MIDI et inversement
35
+ - **Connecteur mock** — couverture de test complète sans matériel MIDI
36
+
37
+ ## Prérequis
38
+
39
+ 1. **[loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)** — créer un port MIDI virtuel (ex. : "loopMIDI Port")
40
+ 2. **[VMPK](https://vmpk.sourceforge.io/)** — configurer l'entrée MIDI sur votre port loopMIDI
41
+ 3. **Node.js 18+**
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ npm install -g @mcptoolshop/pianoai
47
+ ```
48
+
49
+ ## Démarrage rapide
50
+
51
+ ```bash
52
+ # Lister tous les morceaux
53
+ pianai list
54
+
55
+ # Afficher les détails d'un morceau + notes pédagogiques
56
+ pianai info moonlight-sonata-mvt1
57
+
58
+ # Jouer un morceau via VMPK
59
+ pianai play let-it-be
60
+
61
+ # Jouer avec un tempo personnalisé
62
+ pianai play basic-12-bar-blues --tempo 80
63
+
64
+ # Avancer mesure par mesure
65
+ pianai play autumn-leaves --mode measure
66
+
67
+ # Pratique à mi-vitesse
68
+ pianai play moonlight-sonata-mvt1 --speed 0.5
69
+
70
+ # Pratique lente mains séparées
71
+ pianai play dream-on --speed 0.75 --mode hands
72
+ ```
73
+
74
+ ## Serveur MCP
75
+
76
+ Le serveur MCP expose 7 outils pour l'intégration LLM :
77
+
78
+ | Outil | Description |
79
+ |-------|-------------|
80
+ | `list_songs` | Parcourir/rechercher des morceaux par genre, difficulté ou requête |
81
+ | `song_info` | Obtenir le langage musical complet, les objectifs pédagogiques, les suggestions de pratique |
82
+ | `registry_stats` | Nombre de morceaux par genre et difficulté |
83
+ | `teaching_note` | Note pédagogique par mesure, doigtés, dynamiques |
84
+ | `suggest_song` | Obtenir une recommandation selon des critères |
85
+ | `list_measures` | Aperçu des mesures avec notes pédagogiques + avertissements d'analyse |
86
+ | `practice_setup` | Suggérer la vitesse, le mode et les réglages vocaux pour un morceau |
87
+
88
+ ```bash
89
+ # Démarrer le serveur MCP (transport stdio)
90
+ pnpm mcp
91
+ ```
92
+
93
+ ### Configuration Claude Desktop
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "pianai": {
99
+ "command": "pianai-mcp"
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## Commandes CLI
106
+
107
+ | Commande | Description |
108
+ |----------|-------------|
109
+ | `list [--genre <genre>]` | Lister les morceaux disponibles, avec filtre optionnel par genre |
110
+ | `info <song-id>` | Afficher les détails du morceau : langage musical, notes pédagogiques, structure |
111
+ | `play <song-id> [opts]` | Jouer un morceau via VMPK par MIDI |
112
+ | `stats` | Statistiques du registre (morceaux, genres, mesures) |
113
+ | `ports` | Lister les ports de sortie MIDI disponibles |
114
+ | `help` | Afficher les informations d'utilisation |
115
+
116
+ ### Options de lecture
117
+
118
+ | Option | Description |
119
+ |--------|-------------|
120
+ | `--port <name>` | Nom du port MIDI (par défaut : détection automatique de loopMIDI) |
121
+ | `--tempo <bpm>` | Remplacer le tempo par défaut du morceau (10-400 BPM) |
122
+ | `--speed <mult>` | Multiplicateur de vitesse : 0.5 = moitié, 1.0 = normal, 2.0 = double |
123
+ | `--mode <mode>` | Mode de lecture : `full`, `measure`, `hands`, `loop` |
124
+
125
+ ## Moteur pédagogique
126
+
127
+ Le moteur pédagogique déclenche des hooks pendant la lecture. 7 implémentations de hooks couvrent tous les cas d'usage :
128
+
129
+ | Hook | Cas d'usage |
130
+ |------|-------------|
131
+ | `createConsoleTeachingHook()` | CLI — affiche les mesures, moments et complétion dans la console |
132
+ | `createSilentTeachingHook()` | Test — aucune opération |
133
+ | `createRecordingTeachingHook()` | Test — enregistre les événements pour les assertions |
134
+ | `createCallbackTeachingHook(cb)` | Personnalisé — redirige vers n'importe quel callback asynchrone |
135
+ | `createVoiceTeachingHook(sink)` | Voix — produit des `VoiceDirective` pour mcp-voice-soundboard |
136
+ | `createAsideTeachingHook(sink)` | Aside — produit des `AsideDirective` pour la boîte de réception mcp-aside |
137
+ | `composeTeachingHooks(...hooks)` | Multi — dispatch vers plusieurs hooks en série |
138
+
139
+ ### Retour vocal
140
+
141
+ ```typescript
142
+ import { createSession, createVoiceTeachingHook } from "@mcptoolshop/pianoai";
143
+ import { getSong } from "ai-music-sheets";
144
+
145
+ const voiceHook = createVoiceTeachingHook(
146
+ async (directive) => {
147
+ // Rediriger vers voice_speak de mcp-voice-soundboard
148
+ console.log(`[Voice] ${directive.text}`);
149
+ },
150
+ { voice: "narrator", speechSpeed: 0.9 }
151
+ );
152
+
153
+ const session = createSession(getSong("moonlight-sonata-mvt1")!, connector, {
154
+ teachingHook: voiceHook,
155
+ speed: 0.5, // pratique à mi-vitesse
156
+ });
157
+
158
+ await session.play();
159
+ // voiceHook.directives → toutes les instructions vocales émises
160
+ ```
161
+
162
+ ### Composition de hooks
163
+
164
+ ```typescript
165
+ import {
166
+ createVoiceTeachingHook,
167
+ createAsideTeachingHook,
168
+ createRecordingTeachingHook,
169
+ composeTeachingHooks,
170
+ } from "@mcptoolshop/pianoai";
171
+
172
+ // Les trois se déclenchent à chaque événement
173
+ const composed = composeTeachingHooks(
174
+ createVoiceTeachingHook(voiceSink),
175
+ createAsideTeachingHook(asideSink),
176
+ createRecordingTeachingHook()
177
+ );
178
+ ```
179
+
180
+ ## API programmatique
181
+
182
+ ```typescript
183
+ import { getSong } from "ai-music-sheets";
184
+ import { createSession, createVmpkConnector } from "@mcptoolshop/pianoai";
185
+
186
+ const connector = createVmpkConnector({ portName: /loop/i });
187
+ await connector.connect();
188
+
189
+ const song = getSong("autumn-leaves")!;
190
+ const session = createSession(song, connector, {
191
+ mode: "measure",
192
+ tempo: 100,
193
+ speed: 0.75, // 75% de la vitesse pour la pratique
194
+ onProgress: (p) => console.log(p.percent), // "25%", "50%", etc.
195
+ });
196
+
197
+ await session.play(); // joue une mesure, puis pause
198
+ session.next(); // avance à la mesure suivante
199
+ await session.play(); // joue la mesure suivante
200
+ session.setSpeed(1.0); // retour à la vitesse normale
201
+ await session.play(); // joue la mesure suivante à pleine vitesse
202
+ session.stop(); // arrêter et réinitialiser
203
+
204
+ // Vérifier les avertissements d'analyse (notes invalides dans les données du morceau)
205
+ if (session.parseWarnings.length > 0) {
206
+ console.warn("Certaines notes n'ont pas pu être analysées :", session.parseWarnings);
207
+ }
208
+
209
+ await connector.disconnect();
210
+ ```
211
+
212
+ ## Architecture
213
+
214
+ ```
215
+ ai-music-sheets (bibliothèque) pianai (runtime)
216
+ ┌──────────────────────┐ ┌────────────────────────────────┐
217
+ │ SongEntry (hybride) │────────→│ Note Parser (sûr + strict) │
218
+ │ Registry (recherche) │ │ Session Engine (vitesse+suivi) │
219
+ │ 10 morceaux, 10 genres│ │ Teaching Engine (7 hooks) │
220
+ └──────────────────────┘ │ VMPK Connector (JZZ) │
221
+ │ MCP Server (7 outils) │
222
+ │ CLI (barre de progression+voix)│
223
+ └─────────┬──────────────────────┘
224
+ │ MIDI
225
+
226
+ ┌─────────────────┐
227
+ │ loopMIDI → VMPK │
228
+ └─────────────────┘
229
+
230
+ Routage des hooks pédagogiques :
231
+ Session → TeachingHook → VoiceDirective → mcp-voice-soundboard
232
+ → AsideDirective → boîte de réception mcp-aside
233
+ → Log console → terminal CLI
234
+ → Enregistrement → assertions de test
235
+ ```
236
+
237
+ ## Tests
238
+
239
+ ```bash
240
+ pnpm test # 121 tests Vitest (parser + session + teaching + voice + aside)
241
+ pnpm smoke # 20 tests d'intégration (pas de MIDI requis)
242
+ pnpm typecheck # tsc --noEmit
243
+ ```
244
+
245
+ Le connecteur VMPK mock (`createMockVmpkConnector`) enregistre tous les événements MIDI sans matériel, permettant une couverture de test complète. Les fonctions d'analyse sécurisée (`safeParseMeasure`) collectent des objets `ParseWarning` au lieu de lever des exceptions, afin que la lecture continue normalement si un morceau contient des notes malformées.
246
+
247
+ ## Liens connexes
248
+
249
+ - **[ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets)** — La bibliothèque de morceaux : 10 genres, format hybride (métadonnées + langage musical + mesures prêtes pour le code)
250
+
251
+ ## Licence
252
+
253
+ MIT