write
Write TidalCycles/Strudel music patterns to the editor with options for auto-playback and validation to control browser-based music generation.
Instructions
Write pattern to editor with optional auto-play and validation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Pattern code | |
| auto_play | No | Start playback immediately after writing (default: false) | |
| validate | No | Validate pattern before writing (default: true) |
Implementation Reference
- src/server/EnhancedMCPServerFixed.ts:80-92 (registration)Tool registration and schema definition for 'write' tool, including input schema with pattern (required), auto_play, and validate options.{ name: 'write', description: 'Write pattern to editor with optional auto-play and validation', inputSchema: { type: 'object', properties: { pattern: { type: 'string', description: 'Pattern code' }, auto_play: { type: 'boolean', description: 'Start playback immediately after writing (default: false)' }, validate: { type: 'boolean', description: 'Validate pattern before writing (default: true)' } }, required: ['pattern'] } },
- MCP tool handler for 'write': validates input, optionally validates pattern, writes via writePatternSafe, optionally auto-plays.case 'write': InputValidator.validateStringLength(args.pattern, 'pattern', 10000, true); // Validate pattern if requested (default: true) - Issue #40 if (args.validate !== false && this.isInitialized && typeof this.controller.validatePattern === 'function') { try { const validation = await this.controller.validatePattern(args.pattern); if (validation && !validation.valid) { return { success: false, errors: validation.errors, warnings: validation.warnings, suggestions: validation.suggestions, message: `Pattern validation failed: ${validation.errors.join('; ')}` }; } } catch (e) { // Validation failed, but we can still try to write this.logger.warn('Pattern validation threw error, continuing with write'); } } const writeResult = await this.writePatternSafe(args.pattern); // Auto-play if requested - Issue #38 if (args.auto_play && this.isInitialized) { await this.controller.play(); return `${writeResult}. Playing.`; } return writeResult;
- Helper method writePatternSafe: handles uninitialized state by caching pattern, otherwise delegates to controller.writePattern.private async writePatternSafe(pattern: string): Promise<string> { if (!this.isInitialized) { // Store the pattern for later use const id = `pattern_${Date.now()}`; this.generatedPatterns.set(id, pattern); return `Pattern generated (initialize Strudel to use it): ${pattern.substring(0, 50)}...`; } return await this.controller.writePattern(pattern); }
- src/StrudelController.ts:126-173 (helper)Core implementation of writePattern: uses Playwright to manipulate CodeMirror editor in strudel.cc browser page, verifies write, updates cache.async writePattern(pattern: string): Promise<string> { if (!this._page) throw new Error('Browser not initialized. Run init tool first.'); // Invalidate cache before write to prevent stale reads this.invalidateCache(); // Use evaluate for faster direct manipulation const success = await this._page.evaluate((newPattern) => { const editor = document.querySelector('.cm-content') as HTMLElement; if (editor) { const view = (editor as any).__view; if (view) { view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: newPattern } }); return true; } } return false; }, pattern); if (!success) { throw new Error('Failed to write pattern - editor not found or view unavailable'); } // Verify the write by reading back from browser (fixes cache sync issues) const verified = await this._page.evaluate(() => { const editor = document.querySelector('.cm-content') as HTMLElement; if (editor) { const view = (editor as any).__view; if (view && view.state && view.state.doc) { return view.state.doc.toString(); } } return null; }); // Update cache with verified content this.editorCache = verified || pattern; this.cacheTimestamp = Date.now(); // Log warning if verification failed if (verified === null) { this.logger.warn('Pattern write verification failed - using input pattern for cache'); } return `Pattern written (${pattern.length} chars)`; }