Skip to content
twinmind-core-workflow-a logo

Twinmind Core Workflow A

twinmind-core-workflow-a

Execute TwinMind primary workflow: Meeting transcription and summary generation. Use when implementing meeting capture, building transcription features, or automating meeting documentation. Trigger with phrases like "twinmind transcription workflow", "meeting transcription", "capture meeting with...

SKILL.md

Full skill instructions

TwinMind Core Workflow A: Meeting Transcription & Summary

Overview

Primary workflow for capturing meetings, generating transcripts, and creating AI summaries.

Prerequisites

  • Completed twinmind-install-auth setup
  • TwinMind Pro/​Enterprise for API access
  • Valid API credentials configured
  • Audio source available (live or file)

Instructions

Step 1: Initialize Meeting Capture

// src/​workflows/​meeting-capture.ts
import { getTwinMindClient } from '../​twinmind/​client';
import { Transcript, Summary } from '../​twinmind/​types';

interface MeetingOptions {
  title?: string;
  calendarEventId?: string;
  language?: string;
  enableDiarization?: boolean;
}

export class MeetingCapture {
  private client = getTwinMindClient();

  async startLiveCapture(options: MeetingOptions = {}): Promise<string> {
    const response = await this.client.post('/​meetings/​live/​start', {
      title: options.title || `Meeting ${new Date().toISOString()}`,
      calendar_event_id: options.calendarEventId,
      language: options.language || 'auto',
      diarization: options.enableDiarization ?? true,
      model: 'ear-3',
    });

    return response.data.session_id;
  }

  async stopCapture(sessionId: string): Promise<Transcript> {
    const response = await this.client.post(`/​meetings/​live/​${sessionId}/​stop`);
    return response.data.transcript;
  }

  async transcribeRecording(audioUrl: string, options: MeetingOptions = {}): Promise<Transcript> {
    const response = await this.client.post('/​transcribe', {
      audio_url: audioUrl,
      title: options.title,
      language: options.language || 'auto',
      diarization: options.enableDiarization ?? true,
      model: 'ear-3',
    });

    return this.waitForTranscript(response.data.transcript_id);
  }

  private async waitForTranscript(transcriptId: string, maxWaitMs = 300000): Promise<Transcript> {
    const startTime = Date.now();
    const pollIntervalMs = 2000;

    while (Date.now() - startTime < maxWaitMs) {
      const response = await this.client.get(`/​transcripts/​${transcriptId}`);

      if (response.data.status === 'completed') {
        return response.data;
      }

      if (response.data.status === 'failed') {
        throw new Error(`Transcription failed: ${response.data.error}`);
      }

      await new Promise(r => setTimeout(r, pollIntervalMs));
    }

    throw new Error('Transcription timeout');
  }
}

Step 2: Generate AI Summary

// src/​workflows/​summary-generation.ts
export interface SummaryOptions {
  format?: 'brief' | 'detailed' | 'bullet-points';
  includeActionItems?: boolean;
  includeKeyPoints?: boolean;
  maxLength?: number;
}

export class SummaryGenerator {
  private client = getTwinMindClient();

  async generateSummary(
    transcriptId: string,
    options: SummaryOptions = {}
  ): Promise<Summary> {
    const response = await this.client.post('/​summarize', {
      transcript_id: transcriptId,
      format: options.format || 'detailed',
      include_action_items: options.includeActionItems ?? true,
      include_key_points: options.includeKeyPoints ?? true,
      max_length: options.maxLength || 500,
    });

    return response.data;
  }

  async generateFollowUpEmail(transcriptId: string): Promise<string> {
    const response = await this.client.post('/​generate/​follow-up-email', {
      transcript_id: transcriptId,
    });

    return response.data.email_content;
  }

  async generateMeetingNotes(transcriptId: string): Promise<string> {
    const response = await this.client.post('/​generate/​meeting-notes', {
      transcript_id: transcriptId,
      format: 'markdown',
    });

    return response.data.notes;
  }
}

Step 3: Handle Speaker Identification

// src/​workflows/​speaker-handling.ts
export interface Speaker {
  id: string;
  name?: string;
  email?: string;
  speakingTime: number;
  segments: number;
}

export class SpeakerManager {
  async identifySpeakers(transcript: Transcript, attendees?: string[]): Promise<Speaker[]> {
    const speakers = new Map<string, Speaker>();

    for (const segment of transcript.segments) {
      const speakerId = segment.speaker_id || 'unknown';
      const existing = speakers.get(speakerId);

      if (existing) {
        existing.speakingTime += segment.end - segment.start;
        existing.segments += 1;
      } else {
        speakers.set(speakerId, {
          id: speakerId,
          speakingTime: segment.end - segment.start,
          segments: 1,
        });
      }
    }

    // Match speakers to attendees if provided
    if (attendees && attendees.length > 0) {
      // TwinMind can match speakers to calendar attendees
      const matched = await this.matchToAttendees(
        Array.from(speakers.values()),
        attendees
      );
      return matched;
    }

    return Array.from(speakers.values());
  }

  private async matchToAttendees(speakers: Speaker[], attendees: string[]): Promise<Speaker[]> {
    const client = getTwinMindClient();
    const response = await client.post('/​speakers/​match', {
      speakers: speakers.map(s => s.id),
      attendees,
    });

    return speakers.map((speaker, idx) => ({
      ...speaker,
      name: response.data.matches[idx]?.name,
      email: response.data.matches[idx]?.email,
    }));
  }
}

Step 4: Complete Workflow Orchestration

// src/​workflows/​full-meeting-workflow.ts
import { MeetingCapture } from './​meeting-capture';
import { SummaryGenerator } from './​summary-generation';
import { SpeakerManager } from './​speaker-handling';

export interface MeetingResult {
  transcriptId: string;
  transcript: Transcript;
  summary: Summary;
  speakers: Speaker[];
  followUpEmail?: string;
  meetingNotes?: string;
}

export async function processMeeting(
  audioUrl: string,
  options: {
    title?: string;
    attendees?: string[];
    generateEmail?: boolean;
    generateNotes?: boolean;
  } = {}
): Promise<MeetingResult> {
  const capture = new MeetingCapture();
  const summaryGen = new SummaryGenerator();
  const speakerMgr = new SpeakerManager();

  // Step 1: Transcribe
  console.log('Starting transcription...');
  const transcript = await capture.transcribeRecording(audioUrl, {
    title: options.title,
    enableDiarization: true,
  });
  console.log(`Transcription complete: ${transcript.id}`);

  // Step 2: Generate summary (parallel with speaker identification)
  console.log('Generating summary and identifying speakers...');
  const [summary, speakers] = await Promise.all([
    summaryGen.generateSummary(transcript.id, {
      format: 'detailed',
      includeActionItems: true,
      includeKeyPoints: true,
    }),
    speakerMgr.identifySpeakers(transcript, options.attendees),
  ]);

  const result: MeetingResult = {
    transcriptId: transcript.id,
    transcript,
    summary,
    speakers,
  };

  // Step 3: Optional outputs
  if (options.generateEmail) {
    result.followUpEmail = await summaryGen.generateFollowUpEmail(transcript.id);
  }

  if (options.generateNotes) {
    result.meetingNotes = await summaryGen.generateMeetingNotes(transcript.id);
  }

  return result;
}

// Example usage
async function main() {
  const result = await processMeeting(
    'https://storage.example.com/​meetings/​standup-2025-01-15.mp3',
    {
      title: 'Daily Standup - Jan 15',
      attendees: ['[email protected]', '[email protected]'],
      generateEmail: true,
      generateNotes: true,
    }
  );

  console.log('Meeting processed successfully!');
  console.log(`Summary: ${result.summary.summary}`);
  console.log(`Action Items: ${result.summary.action_items.length}`);
  console.log(`Speakers: ${result.speakers.map(s => s.name || s.id).join(', ')}`);
}

Output

  • Complete meeting transcript with timestamps
  • Speaker-labeled segments
  • AI-generated summary
  • Extracted action items with assignees
  • Optional follow-up email draft
  • Optional formatted meeting notes

Example console output:

Starting transcription...
Transcription complete: tr_abc123
Generating summary and identifying speakers...
Meeting processed successfully!
Summary: Daily standup covering sprint progress and blockers...
Action Items: 3
Speakers: Alice, Bob, Charlie

Error Handling

ErrorCauseSolution
Transcription timeoutLarge audio fileIncrease maxWaitMs or use async callback
Speaker match failedNo calendar dataProvide attendees list manually
Summary generation failedTranscript too shortEnsure minimum 30s of audio
Audio format unsupportedWrong codecConvert to MP3/​WAV/​M4A
Rate limit exceededToo many requestsImplement queue-based processing

Audio Format Support

FormatExtensionSupportedNotes
MP3.mp3YesRecommended
WAV.wavYesBest quality
M4A.m4aYesiOS recordings
WebM.webmYesBrowser recordings
OGG.oggYesOpen format
FLAC.flacYesLossless

Resources

Next Steps

For action item extraction and follow-up automation, see twinmind-core-workflow-b.

More Productivity & Planning skills

brainstorming logo
Productivity & Planning

brainstorming

Structured design dialogue that validates ideas before implementation begins.

295.4K 385.7K
View
ui-ux-pro-max logo
Productivity & Planning

ui-ux-pro-max

Comprehensive design intelligence for web and mobile UI/UX across 10 technology stacks.

133.1K 383.9K
View
writing-plans logo
Productivity & Planning

writing-plans

Comprehensive implementation plans for multi-step tasks, breaking down specs into bite-sized, testable steps.

295.4K 268K
View
using-superpowers logo
Productivity & Planning

using-superpowers

Introduction to the obra skills system with mandatory skill invocation rules and best practices.

295.4K 259.8K
View
executing-plans logo
Productivity & Planning

executing-plans

Execute a written implementation plan with critical review and task checkpoints.

295.4K 229.1K
View
dispatching-parallel-agents logo
Productivity & Planning

dispatching-parallel-agents

Delegate independent tasks to specialized agents working concurrently with isolated context.

295.4K 206.3K
View
using-git-worktrees logo
Productivity & Planning

using-git-worktrees

Isolated git worktrees with smart directory selection and safety verification.

295.4K 205.2K
View
webapp-testing logo
Productivity & Planning

webapp-testing

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

179.7K 170.6K
View
content-strategy logo
Productivity & Planning

content-strategy

Plan searchable and shareable content that drives traffic, builds authority, and generates leads.

53.3K 150.9K
View
repo-intake-and-plan logo
Productivity & Planning

repo-intake-and-plan

README-first repository scanner that extracts commands and classifies reproduction candidates without executing them.

497 139.6K
View
marketing-ideas logo
Productivity & Planning

marketing-ideas

Brainstorm and prioritize marketing strategies tailored to your SaaS stage, budget, and goals.

53.3K 137.2K
View
site-architecture logo
Productivity & Planning

site-architecture

Plan and optimize your website's page hierarchy, navigation, URL structure, and internal linking.

53.3K 112.8K
View

Productivity AI tools

Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View
SaveDay logo
Productivity

SaveDay

Capture, organize, and utilize your knowledge effortlessly.

Free
View
A
Productivity

Any Summary

Instant Summaries of Audio & Video Interviews with AnySummary

Freemium
View
M
Productivity

Map This

Transform PDFs into engaging mind maps.

Freemium
View
ChatPDF logo
Productivity

ChatPDF

Chat with any PDF instantly

Free
View
I
Productivity

intellisay

Create an optimal daily plan using your voice

Paid
View
A
Productivity

Aurora AI

A productivity platform to centralize organizational knowledge and workflows with contextual AI assistance.

Paid
View
AskYourPDF logo
Productivity

AskYourPDF

AskYourPDF Pricing Plans: Tailored to Your Needs

Free
View