home / skills / jeremylongshore / claude-code-plugins-plus-skills / twinmind-local-dev-loop
/plugins/saas-packs/twinmind-pack/skills/twinmind-local-dev-loop
This skill helps set up a productive local TwinMind development loop for API integration, testing calls, and building meeting automation.
npx playbooks add skill jeremylongshore/claude-code-plugins-plus-skills --skill twinmind-local-dev-loopReview the files below or copy the command above to add this skill to your agents.
---
name: twinmind-local-dev-loop
description: |
Set up local development workflow with TwinMind API integration.
Use when building applications that integrate TwinMind transcription,
testing API calls locally, or developing meeting automation tools.
Trigger with phrases like "twinmind dev setup", "twinmind local development",
"twinmind API testing", "build with twinmind".
allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pip:*), Bash(curl:*)
version: 1.0.0
license: MIT
author: Jeremy Longshore <[email protected]>
---
# TwinMind Local Dev Loop
## Overview
Configure a productive local development environment for TwinMind API integration.
## Prerequisites
- TwinMind Pro or Enterprise account (API access)
- Node.js 18+ or Python 3.10+
- API key from TwinMind dashboard
- Local development environment
## Instructions
### Step 1: Project Setup
```bash
# Create project directory
mkdir twinmind-integration && cd twinmind-integration
# Initialize Node.js project
npm init -y
# Install dependencies
npm install dotenv axios zod typescript ts-node @types/node
# Initialize TypeScript
npx tsc --init
```
### Step 2: Configure Environment
```bash
# Create environment file
cat > .env << 'EOF'
TWINMIND_API_KEY=your-api-key-here
TWINMIND_API_URL=https://api.twinmind.com/v1
TWINMIND_WEBHOOK_SECRET=your-webhook-secret
NODE_ENV=development
EOF
# Add to .gitignore
echo ".env" >> .gitignore
echo "node_modules" >> .gitignore
```
### Step 3: Create TwinMind Client
```typescript
// src/twinmind/client.ts
import axios, { AxiosInstance } from 'axios';
import { z } from 'zod';
// Response schemas
const TranscriptSchema = z.object({
id: z.string(),
text: z.string(),
duration_seconds: z.number(),
language: z.string(),
speakers: z.array(z.object({
id: z.string(),
name: z.string().optional(),
segments: z.array(z.object({
start: z.number(),
end: z.number(),
text: z.string(),
confidence: z.number(),
})),
})),
created_at: z.string(),
});
const SummarySchema = z.object({
id: z.string(),
transcript_id: z.string(),
summary: z.string(),
action_items: z.array(z.object({
text: z.string(),
assignee: z.string().optional(),
due_date: z.string().optional(),
})),
key_points: z.array(z.string()),
});
export type Transcript = z.infer<typeof TranscriptSchema>;
export type Summary = z.infer<typeof SummarySchema>;
export class TwinMindClient {
private client: AxiosInstance;
constructor(apiKey: string, baseUrl?: string) {
this.client = axios.create({
baseURL: baseUrl || 'https://api.twinmind.com/v1',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
timeout: 30000,
});
}
async healthCheck(): Promise<boolean> {
const response = await this.client.get('/health');
return response.status === 200;
}
async transcribe(audioUrl: string, options?: {
language?: string;
diarization?: boolean;
model?: 'ear-3' | 'ear-2';
}): Promise<Transcript> {
const response = await this.client.post('/transcribe', {
audio_url: audioUrl,
language: options?.language || 'auto',
diarization: options?.diarization ?? true,
model: options?.model || 'ear-3',
});
return TranscriptSchema.parse(response.data);
}
async summarize(transcriptId: string): Promise<Summary> {
const response = await this.client.post('/summarize', {
transcript_id: transcriptId,
});
return SummarySchema.parse(response.data);
}
async search(query: string, options?: {
limit?: number;
date_from?: string;
date_to?: string;
}): Promise<Transcript[]> {
const response = await this.client.get('/search', {
params: {
q: query,
limit: options?.limit || 10,
date_from: options?.date_from,
date_to: options?.date_to,
},
});
return z.array(TranscriptSchema).parse(response.data.results);
}
}
```
### Step 4: Create Dev Runner Script
```typescript
// src/dev.ts
import 'dotenv/config';
import { TwinMindClient } from './twinmind/client';
async function main() {
const client = new TwinMindClient(process.env.TWINMIND_API_KEY!);
// Health check
console.log('Checking TwinMind API health...');
const healthy = await client.healthCheck();
console.log(`API Status: ${healthy ? 'Healthy' : 'Unhealthy'}`);
// Example: Transcribe audio file
// const transcript = await client.transcribe('https://example.com/meeting.mp3');
// console.log('Transcript:', transcript);
// Example: Generate summary
// const summary = await client.summarize(transcript.id);
// console.log('Summary:', summary);
// Example: Search memory vault
// const results = await client.search('budget review');
// console.log('Search results:', results);
}
main().catch(console.error);
```
### Step 5: Configure Dev Scripts
```json
// package.json scripts
{
"scripts": {
"dev": "ts-node src/dev.ts",
"build": "tsc",
"test": "jest",
"lint": "eslint src/**/*.ts",
"typecheck": "tsc --noEmit"
}
}
```
### Step 6: Create Test Fixtures
```typescript
// tests/fixtures/mock-responses.ts
export const mockTranscript = {
id: 'tr_test_123',
text: 'Welcome to the meeting. Today we discuss the project timeline.',
duration_seconds: 45,
language: 'en',
speakers: [
{
id: 'spk_1',
name: 'Host',
segments: [
{
start: 0,
end: 5.2,
text: 'Welcome to the meeting.',
confidence: 0.97,
},
{
start: 5.5,
end: 12.1,
text: 'Today we discuss the project timeline.',
confidence: 0.95,
},
],
},
],
created_at: '2025-01-15T10:00:00Z',
};
export const mockSummary = {
id: 'sum_test_456',
transcript_id: 'tr_test_123',
summary: 'Brief meeting to discuss project timeline and milestones.',
action_items: [
{
text: 'Review timeline document',
assignee: 'John',
due_date: '2025-01-20',
},
],
key_points: [
'Project kickoff confirmed',
'Timeline review scheduled',
],
};
```
### Step 7: Run Development Loop
```bash
# Start development
npm run dev
# Watch mode (requires nodemon)
npm install -D nodemon
npx nodemon --exec ts-node src/dev.ts
# Run with debug logging
DEBUG=twinmind:* npm run dev
```
## Output
- Project structure with TypeScript configuration
- TwinMind client with type-safe schemas
- Environment configuration
- Development scripts
- Test fixtures for offline development
## Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| API key missing | .env not loaded | Check dotenv import |
| Connection refused | Wrong API URL | Verify TWINMIND_API_URL |
| Rate limited | Too many requests | Add delay between calls |
| Schema validation failed | API response changed | Update Zod schemas |
| Timeout | Large audio file | Increase timeout value |
## Project Structure
```
twinmind-integration/
├── src/
│ ├── twinmind/
│ │ ├── client.ts # API client
│ │ ├── types.ts # TypeScript types
│ │ └── errors.ts # Error classes
│ ├── services/
│ │ └── meeting.ts # Business logic
│ └── dev.ts # Development entry
├── tests/
│ ├── fixtures/
│ │ └── mock-responses.ts
│ └── twinmind.test.ts
├── .env # Environment (gitignored)
├── .env.example # Template
├── package.json
└── tsconfig.json
```
## Resources
- [TwinMind API Documentation](https://twinmind.com/docs/api)
- [Ear-3 Model Specification](https://twinmind.com/ear-3)
- [Zod Documentation](https://zod.dev/)
## Next Steps
Apply patterns in `twinmind-sdk-patterns` for production-ready code.
This skill sets up a reproducible local development loop for integrating the TwinMind transcription API into applications. It provides a TypeScript client, environment configuration, dev runner, test fixtures, and scripts to run and iterate quickly. The goal is to make building, testing, and debugging TwinMind-powered meeting automation and transcription features fast and safe locally.
The skill scaffolds a small TypeScript project, installs runtime and dev dependencies, and creates a TwinMind client wrapper with Zod schemas for type-safe responses. It reads credentials from a .env file, exposes health check, transcribe, summarize, and search methods, and includes a dev script to run sample flows. Mock fixtures and test scripts let you run the loop offline and validate behavior before hitting the real API.
What do I need before starting?
A TwinMind Pro/Enterprise account with an API key, Node.js 18+ or Python 3.10+, and a local dev environment.
How do I avoid leaking my API key?
Keep keys in .env, add .env to .gitignore, and use environment variables or secrets manager in CI and production.
Can I run the loop without network access?
Yes — use the included mock fixtures and unit tests to simulate transcripts and summaries offline.