speak-local-dev-loop
Configure Speak local development with hot reload, testing, and mock tutors. Use when setting up a development environment, configuring test workflows, or establishing a fast iteration cycle with Speak language learning. Trigger with phrases like "speak dev setup", "speak local development", "speak dev environment", "develop with speak". allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore <jeremy@intentsolutions.io>
Allowed Tools
No tools specified
Provided by Plugin
speak-pack
Claude Code skill pack for Speak AI Language Learning Platform (24 skills)
Installation
This skill is included in the speak-pack plugin:
/plugin install speak-pack@claude-code-plugins-plus
Click to copy
Instructions
# Speak Local Dev Loop
## Overview
Set up a fast, reproducible local development workflow for Speak language learning integrations.
## Prerequisites
- Completed `speak-install-auth` setup
- Node.js 18+ with npm/pnpm
- Code editor with TypeScript support
- Git for version control
- Audio testing tools (optional)
## Instructions
### Step 1: Create Project Structure
```
my-speak-project/
โโโ src/
โ โโโ speak/
โ โ โโโ client.ts # Speak client wrapper
โ โ โโโ config.ts # Configuration management
โ โ โโโ tutor.ts # AI tutor service
โ โ โโโ speech.ts # Speech recognition utilities
โ โ โโโ utils.ts # Helper functions
โ โโโ lessons/
โ โ โโโ vocabulary.ts # Vocabulary lesson logic
โ โ โโโ conversation.ts # Conversation practice
โ โ โโโ pronunciation.ts # Pronunciation training
โ โโโ index.ts
โโโ tests/
โ โโโ unit/
โ โ โโโ speak.test.ts
โ โโโ integration/
โ โ โโโ lessons.test.ts
โ โโโ mocks/
โ โโโ speak-mock.ts # Mock tutor responses
โโโ .env.local # Local secrets (git-ignored)
โโโ .env.example # Template for team
โโโ .env.test # Test environment
โโโ package.json
```
### Step 2: Configure Environment
```bash
# Copy environment template
cp .env.example .env.local
# Create test environment
cat > .env.test << 'EOF'
SPEAK_API_KEY=test-key-for-mocks
SPEAK_APP_ID=test-app-id
SPEAK_MOCK_MODE=true
SPEAK_TARGET_LANGUAGE=es
EOF
# Install dependencies
npm install
# Start development server
npm run dev
```
### Step 3: Setup Hot Reload
```json
{
"scripts": {
"dev": "tsx watch src/index.ts",
"dev:lesson": "tsx watch src/lessons/conversation.ts",
"test": "vitest",
"test:watch": "vitest --watch",
"test:integration": "vitest run tests/integration"
}
}
```
### Step 4: Configure Testing with Mocks
```typescript
// tests/mocks/speak-mock.ts
import { vi } from 'vitest';
export const mockTutorResponse = {
text: "Muy bien! Your pronunciation is improving.",
audioUrl: 'https://speak.com/mock-audio.mp3',
pronunciationScore: 85,
grammarCorrections: [],
suggestions: ['Try rolling your Rs more'],
};
export const mockSpeakClient = {
health: {
check: vi.fn().mockResolvedValue({ healthy: true }),
},
tutor: {
startSession: vi.fn().mockResolvedValue({
id: 'session-123',
status: 'active',
}),
getPrompt: vi.fn().mockResolvedValue({
text: 'Let\'s practice greetings in Spanish!',
audioUrl: 'https://speak.com/mock-prompt.mp3',
}),
submitResponse: vi.fn().mockResolvedValue(mockTutorResponse),
},
speech: {
recognize: vi.fn().mockResolvedValue({
transcript: 'Hola, como estas',
confidence: 0.92,
}),
score: vi.fn().mockResolvedValue({
overall: 85,
fluency: 82,
accuracy: 88,
pronunciation: 85,
}),
},
};
vi.mock('@speak/language-sdk', () => ({
SpeakClient: vi.fn().mockImplementation(() => mockSpeakClient),
AITutor: vi.fn(),
SpeechRecognizer: vi.fn(),
}));
```
### Step 5: Write Unit Tests
```typescript
// tests/unit/speak.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mockSpeakClient } from '../mocks/speak-mock';
import { SpeakService } from '../../src/speak/client';
describe('Speak Client', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should initialize with API key', () => {
const service = new SpeakService({ apiKey: 'test-key', appId: 'test-app' });
expect(service).toBeDefined();
});
it('should verify health check', async () => {
const result = await mockSpeakClient.health.check();
expect(result.healthy).toBe(true);
});
it('should start a lesson session', async () => {
const session = await mockSpeakClient.tutor.startSession({
language: 'es',
topic: 'greetings',
});
expect(session.id).toBe('session-123');
expect(session.status).toBe('active');
});
it('should return pronunciation feedback', async () => {
const feedback = await mockSpeakClient.tutor.submitResponse({
text: 'Hola',
});
expect(feedback.pronunciationScore).toBeGreaterThan(0);
expect(feedback.pronunciationScore).toBeLessThanOrEqual(100);
});
});
```
### Step 6: Create Mock Lesson Runner
```typescript
// src/dev/mock-lesson.ts
import { SpeakClient } from '@speak/language-sdk';
const isMockMode = process.env.SPEAK_MOCK_MODE === 'true';
export async function runMockLesson() {
if (isMockMode) {
console.log('Running in MOCK mode');
// Return mock responses without API calls
return {
prompt: 'Mock: Let\'s practice Spanish!',
feedback: { score: 85, message: 'Mock feedback' },
};
}
// Real API calls
const client = new SpeakClient({
apiKey: process.env.SPEAK_API_KEY!,
appId: process.env.SPEAK_APP_ID!,
language: 'es',
});
// ... real implementation
}
```
## Output
- Working development environment with hot reload
- Configured test suite with mocking
- Environment variable management
- Fast iteration cycle for Speak development
- Mock tutor for offline development
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| Module not found | Missing dependency | Run `npm install` |
| Port in use | Another process | Kill process or change port |
| Env not loaded | Missing .env.local | Copy from .env.example |
| Test timeout | Slow network | Use mocks or increase timeout |
| Audio not playing | Browser security | Use HTTPS in dev |
## Examples
### Mock Speech Recognition
```typescript
// tests/mocks/speech-mock.ts
export function createMockSpeechRecognizer() {
return {
start: vi.fn(),
stop: vi.fn(),
onResult: vi.fn(),
simulateResult: (text: string, score: number) => {
return {
transcript: text,
pronunciationScore: score,
timing: {
duration: 2500,
words: [
{ word: 'Hola', start: 0, end: 500, score: 90 },
{ word: 'como', start: 600, end: 1000, score: 85 },
{ word: 'estas', start: 1100, end: 1600, score: 80 },
],
},
};
},
};
}
```
### Debug Mode with Verbose Logging
```bash
# Enable verbose logging for Speak operations
DEBUG=speak:* npm run dev
# Log only speech recognition
DEBUG=speak:speech npm run dev
# Log tutor interactions
DEBUG=speak:tutor npm run dev
```
### Development Scripts
```json
{
"scripts": {
"dev": "tsx watch src/index.ts",
"dev:mock": "SPEAK_MOCK_MODE=true tsx watch src/index.ts",
"test:unit": "vitest run tests/unit",
"test:integration": "vitest run tests/integration",
"lesson:spanish": "tsx src/lessons/spanish-basics.ts",
"lesson:korean": "SPEAK_TARGET_LANGUAGE=ko tsx src/lessons/korean-basics.ts"
}
}
```
## Resources
- [Speak SDK Reference](https://developer.speak.com/sdk)
- [Vitest Documentation](https://vitest.dev/)
- [tsx Documentation](https://github.com/esbuild-kit/tsx)
- [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)
## Next Steps
See `speak-sdk-patterns` for production-ready code patterns.