@grunnverk/audio-tools 1.5.3 → 1.5.5

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.
package/README.md CHANGED
@@ -628,7 +628,7 @@ recordAndTranscribeVoiceNote().catch(error => {
628
628
 
629
629
  ### Audio Preferences
630
630
 
631
- The library uses `@theunwalked/unplayable` which stores audio device preferences in:
631
+ The library uses `@utilarium/unplayable` which stores audio device preferences in:
632
632
  ```
633
633
  ~/.unplayable/audio-preferences.json
634
634
  ```
@@ -639,7 +639,7 @@ You can manually edit this file to set default devices.
639
639
 
640
640
  ### Dependencies
641
641
 
642
- - **[@theunwalked/unplayable](https://github.com/theunwalked/unplayable)** - Cross-platform audio recording
642
+ - **[@utilarium/unplayable](https://github.com/utilarium/unplayable)** - Cross-platform audio recording
643
643
  - **[@grunnverk/ai-service](https://github.com/grunnverk/ai-service)** - OpenAI Whisper integration
644
644
  - **[@grunnverk/shared](https://github.com/grunnverk/shared)** - Optional shared utilities
645
645
  - **winston** - Optional structured logging
@@ -725,7 +725,7 @@ Apache-2.0 License - see [LICENSE](LICENSE) file for details.
725
725
 
726
726
  - **[@grunnverk/ai-service](https://github.com/grunnverk/ai-service)** - AI services including transcription
727
727
  - **[@grunnverk/shared](https://github.com/grunnverk/shared)** - Shared utilities
728
- - **[@theunwalked/unplayable](https://github.com/theunwalked/unplayable)** - Cross-platform audio library
728
+ - **[@utilarium/unplayable](https://github.com/utilarium/unplayable)** - Cross-platform audio library
729
729
 
730
730
  ## 💬 Support
731
731
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { getLogger } from '@grunnverk/shared';
2
2
  export { getLogger, setLogger } from '@grunnverk/shared';
3
- import { selectAndConfigureAudioDevice, processAudio } from '@theunwalked/unplayable';
3
+ import { selectAndConfigureAudioDevice, processAudio } from '@utilarium/unplayable';
4
4
  import { homedir } from 'os';
5
5
  import { join } from 'path';
6
6
  import { promises } from 'fs';
@@ -248,11 +248,11 @@ function _define_property(obj, key, value) {
248
248
 
249
249
  /**
250
250
  * List all available audio input devices
251
- * Note: This is a placeholder - @theunwalked/unplayable doesn't provide a direct API for this
251
+ * Note: This is a placeholder - @utilarium/unplayable doesn't provide a direct API for this
252
252
  * In practice, you would use selectAndConfigureAudioDevice for device selection
253
253
  */ async function listAudioDevices() {
254
254
  const logger = getLogger();
255
- // This would require extending @theunwalked/unplayable or using a different library
255
+ // This would require extending @utilarium/unplayable or using a different library
256
256
  logger.warn('listAudioDevices is not fully implemented - use selectDeviceInteractive instead');
257
257
  return [];
258
258
  }
@@ -269,7 +269,7 @@ function _define_property(obj, key, value) {
269
269
  return devices.find((d)=>d.id === idOrName) || devices.find((d)=>d.name === idOrName) || null;
270
270
  }
271
271
  /**
272
- * Interactive device selection using @theunwalked/unplayable
272
+ * Interactive device selection using @utilarium/unplayable
273
273
  * This function uses the built-in interactive device selector
274
274
  */ async function selectDeviceInteractive() {
275
275
  const logger = getLogger();
@@ -284,7 +284,7 @@ function _define_property(obj, key, value) {
284
284
  }
285
285
 
286
286
  /**
287
- * Record audio using @theunwalked/unplayable
287
+ * Record audio using @utilarium/unplayable
288
288
  */ async function recordAudio(options = {}) {
289
289
  const logger = getLogger();
290
290
  const { duration, outputPath } = options;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/countdown.ts","../src/devices.ts","../src/recording.ts","../src/transcription.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Countdown timer utility for audio recording sessions\n * Provides a visual countdown with beep warnings and color changes\n */\n\nexport interface CountdownOptions {\n /** Duration in seconds */\n durationSeconds: number;\n /** Show beep warning at 30 seconds remaining */\n beepAt30Seconds?: boolean;\n /** Change color to red at 30 seconds remaining */\n redAt30Seconds?: boolean;\n /** Callback function called every second with remaining time */\n onTick?: (remainingSeconds: number) => void;\n /** Callback function called when countdown reaches zero */\n onComplete?: () => void;\n /** Whether to clear the countdown line when finished */\n clearOnComplete?: boolean;\n}\n\n/**\n * ANSI escape codes for terminal control\n */\nconst ANSI = {\n // Cursor movement\n CURSOR_UP: '\\x1b[1A',\n CURSOR_TO_START: '\\x1b[0G',\n CLEAR_LINE: '\\x1b[2K',\n\n // Colors\n RED: '\\x1b[31m',\n GREEN: '\\x1b[32m',\n YELLOW: '\\x1b[33m',\n BLUE: '\\x1b[34m',\n MAGENTA: '\\x1b[35m',\n CYAN: '\\x1b[36m',\n WHITE: '\\x1b[37m',\n RESET: '\\x1b[0m',\n\n // Text styles\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m'\n} as const;\n\n/**\n * Format seconds into MM:SS format\n */\nfunction formatTime(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n}\n\n/**\n * Generate a beep sound using process.stdout.write with ASCII bell character\n */\nfunction beep(): void {\n process.stdout.write('\\x07'); // ASCII bell character\n}\n\n/**\n * Check if terminal supports colors and cursor movement\n */\nfunction supportsAnsi(): boolean {\n return process.stdout.isTTY &&\n process.env.TERM !== 'dumb' &&\n !process.env.NO_COLOR;\n}\n\n/**\n * Display a live countdown timer that updates in place\n */\nexport class CountdownTimer {\n private options: Required<CountdownOptions>;\n private intervalId: NodeJS.Timeout | null = null;\n private currentSeconds: number;\n private hasBeepedAt30: boolean = false;\n private isFirstDisplay: boolean = true;\n private supportsAnsi: boolean;\n private cleanupHandlers: Array<() => void> = [];\n private isDestroyed = false;\n\n constructor(options: CountdownOptions) {\n this.options = {\n beepAt30Seconds: true,\n redAt30Seconds: true,\n onTick: () => {},\n onComplete: () => {},\n clearOnComplete: false,\n ...options\n };\n this.currentSeconds = this.options.durationSeconds;\n this.supportsAnsi = supportsAnsi();\n\n // Set up cleanup handlers for process termination\n this.setupCleanupHandlers();\n }\n\n /**\n * Start the countdown timer\n */\n start(): Promise<void> {\n return new Promise((resolve) => {\n // Handle zero seconds case\n if (this.currentSeconds <= 0) {\n this.options.onComplete();\n resolve();\n return;\n }\n\n // Display initial countdown\n this.displayCountdown();\n\n this.intervalId = setInterval(() => {\n // Check if destroyed before processing\n if (this.isDestroyed) {\n clearInterval(this.intervalId!);\n resolve();\n return;\n }\n\n this.currentSeconds--;\n\n // Check for beep warning\n if (this.options.beepAt30Seconds &&\n this.currentSeconds === 30 &&\n !this.hasBeepedAt30) {\n beep();\n this.hasBeepedAt30 = true;\n }\n\n // Call tick callback\n this.options.onTick(this.currentSeconds);\n\n if (this.currentSeconds <= 0) {\n this.stop();\n this.options.onComplete();\n resolve();\n } else {\n this.displayCountdown();\n }\n }, 1000);\n });\n }\n\n /**\n * Stop the countdown timer\n */\n stop(): void {\n if (this.isDestroyed) {\n return;\n }\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (this.options.clearOnComplete && this.supportsAnsi) {\n // Clear the countdown line\n process.stdout.write(ANSI.CURSOR_TO_START + ANSI.CLEAR_LINE);\n } else if (!this.isFirstDisplay) {\n // Add a newline if we've been updating in place\n process.stdout.write('\\n');\n }\n }\n\n /**\n * Get current remaining time\n */\n getRemainingSeconds(): number {\n return this.currentSeconds;\n }\n\n /**\n * Display the countdown timer\n */\n private displayCountdown(): void {\n const timeString = formatTime(this.currentSeconds);\n const isWarningTime = this.currentSeconds <= 30;\n\n let output: string;\n\n if (this.supportsAnsi) {\n // Use colors and in-place updating if supported\n if (!this.isFirstDisplay) {\n // Move cursor up and clear the line to overwrite previous countdown\n process.stdout.write(ANSI.CURSOR_UP + ANSI.CURSOR_TO_START + ANSI.CLEAR_LINE);\n }\n\n const color = isWarningTime && this.options.redAt30Seconds ? ANSI.RED : ANSI.CYAN;\n const style = isWarningTime ? ANSI.BOLD : '';\n\n output = `${color}${style}⏱️ Recording time remaining: ${timeString}${ANSI.RESET}`;\n } else {\n // Fallback for terminals that don't support ANSI\n const warning = isWarningTime ? ' ⚠️ ' : '';\n output = `⏱️ Recording time remaining: ${timeString}${warning}`;\n }\n\n process.stdout.write(output + '\\n');\n this.isFirstDisplay = false;\n }\n\n /**\n * Set up cleanup handlers for process termination and uncaught exceptions\n */\n private setupCleanupHandlers(): void {\n // Skip setting up process listeners in test environments to avoid listener leaks\n if (process.env.NODE_ENV === 'test' || process.env.VITEST) {\n return;\n }\n\n const cleanup = () => {\n this.destroy();\n };\n\n // Handle various exit scenarios\n const exitHandler = () => cleanup();\n const uncaughtExceptionHandler = (error: Error) => {\n cleanup();\n // Re-throw to maintain normal error handling\n throw error;\n };\n\n process.on('exit', exitHandler);\n process.on('SIGINT', exitHandler);\n process.on('SIGTERM', exitHandler);\n process.on('uncaughtException', uncaughtExceptionHandler);\n process.on('unhandledRejection', cleanup);\n\n // Store handlers for removal during destroy\n this.cleanupHandlers = [\n () => process.removeListener('exit', exitHandler),\n () => process.removeListener('SIGINT', exitHandler),\n () => process.removeListener('SIGTERM', exitHandler),\n () => process.removeListener('uncaughtException', uncaughtExceptionHandler),\n () => process.removeListener('unhandledRejection', cleanup)\n ];\n }\n\n /**\n * Destroy the timer and clean up all resources\n */\n destroy(): void {\n if (this.isDestroyed) {\n return;\n }\n\n this.isDestroyed = true;\n this.stop();\n\n // Remove all process event listeners\n this.cleanupHandlers.forEach(handler => {\n try {\n handler();\n } catch {\n // Ignore errors during cleanup\n }\n });\n this.cleanupHandlers = [];\n }\n\n /**\n * Check if the timer has been destroyed\n */\n isTimerDestroyed(): boolean {\n return this.isDestroyed;\n }\n}\n\n/**\n * Create and start a countdown timer (convenience function)\n */\nexport async function startCountdown(options: CountdownOptions): Promise<void> {\n const timer = new CountdownTimer(options);\n return timer.start();\n}\n\n/**\n * Create a countdown timer for audio recording with sensible defaults\n */\nexport function createAudioRecordingCountdown(durationSeconds: number): CountdownTimer {\n return new CountdownTimer({\n durationSeconds,\n beepAt30Seconds: true,\n redAt30Seconds: true,\n clearOnComplete: true\n });\n}\n\n/**\n * Simple countdown function for backwards compatibility\n * @param seconds Number of seconds to count down\n * @param onTick Optional callback called on each tick\n * @deprecated Use CountdownTimer or startCountdown for more features\n */\nexport async function countdown(\n seconds: number,\n onTick?: (remaining: number) => void\n): Promise<void> {\n const options: CountdownOptions = {\n durationSeconds: seconds,\n beepAt30Seconds: false,\n redAt30Seconds: false,\n clearOnComplete: false\n };\n\n if (onTick) {\n options.onTick = onTick;\n }\n\n await startCountdown(options);\n}\n","/**\n * Audio device detection and selection\n */\n\nimport { selectAndConfigureAudioDevice } from '@theunwalked/unplayable';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { getLogger } from '@grunnverk/shared';\nimport type { AudioDevice } from './types';\n\n/**\n * List all available audio input devices\n * Note: This is a placeholder - @theunwalked/unplayable doesn't provide a direct API for this\n * In practice, you would use selectAndConfigureAudioDevice for device selection\n */\nexport async function listAudioDevices(): Promise<AudioDevice[]> {\n const logger = getLogger();\n\n // This would require extending @theunwalked/unplayable or using a different library\n logger.warn('listAudioDevices is not fully implemented - use selectDeviceInteractive instead');\n return [];\n}\n\n/**\n * Get the default audio input device\n */\nexport async function getDefaultDevice(): Promise<AudioDevice | null> {\n const devices = await listAudioDevices();\n return devices.find((d) => d.isDefault) || devices[0] || null;\n}\n\n/**\n * Find device by ID or name\n */\nexport async function findDevice(idOrName: string): Promise<AudioDevice | null> {\n const devices = await listAudioDevices();\n\n return (\n devices.find((d) => d.id === idOrName) ||\n devices.find((d) => d.name === idOrName) ||\n null\n );\n}\n\n/**\n * Interactive device selection using @theunwalked/unplayable\n * This function uses the built-in interactive device selector\n */\nexport async function selectDeviceInteractive(): Promise<string> {\n const logger = getLogger();\n\n try {\n const preferencesDir = join(homedir(), '.unplayable');\n const result = await selectAndConfigureAudioDevice(preferencesDir, logger, false);\n return result;\n } catch (error) {\n logger.error('Device selection failed:', error);\n throw new Error(`Device selection failed: ${error}`);\n }\n}\n\n","/**\n * Audio recording functionality\n */\n\nimport { processAudio } from '@theunwalked/unplayable';\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { getLogger } from '@grunnverk/shared';\nimport type { RecordingOptions, RecordingResult } from './types';\n\n/**\n * Record audio using @theunwalked/unplayable\n */\nexport async function recordAudio(\n options: RecordingOptions = {}\n): Promise<RecordingResult> {\n const logger = getLogger();\n\n const {\n duration,\n outputPath,\n } = options;\n\n const startTime = Date.now();\n\n try {\n logger.info('Starting audio recording...');\n logger.info('Press ENTER to stop recording');\n\n const audioResult = await processAudio({\n file: undefined,\n maxRecordingTime: duration,\n outputDirectory: outputPath ? outputPath.substring(0, outputPath.lastIndexOf('/')) : 'output',\n debug: false\n });\n\n if (audioResult.cancelled) {\n throw new Error('Recording cancelled by user');\n }\n\n const endTime = Date.now();\n const actualDuration = (endTime - startTime) / 1000;\n\n // Get file stats\n const filePath = audioResult.audioFilePath || join('output', `recording-${Date.now()}.wav`);\n const stats = await fs.stat(filePath);\n\n logger.info(`Recording complete: ${filePath}`);\n logger.info(`Duration: ${actualDuration.toFixed(2)} seconds`);\n logger.info(`File size: ${(stats.size / 1024).toFixed(2)} KB`);\n\n return {\n filePath,\n duration: actualDuration,\n fileSize: stats.size,\n };\n } catch (error) {\n logger.error('Recording failed:', error);\n throw new Error(`Recording failed: ${error}`);\n }\n}\n\n/**\n * Get timestamped filename for archiving\n */\nfunction getTimestampedFilename(baseName: string, extension: string = '.json'): string {\n const now = new Date();\n\n // Format as YYMMdd-HHmm (e.g., 250701-1030)\n const yy = now.getFullYear().toString().slice(-2);\n const mm = (now.getMonth() + 1).toString().padStart(2, '0');\n const dd = now.getDate().toString().padStart(2, '0');\n const hh = now.getHours().toString().padStart(2, '0');\n const min = now.getMinutes().toString().padStart(2, '0');\n\n const timestamp = `${yy}${mm}${dd}-${hh}${min}`;\n\n return `${timestamp}-${baseName}${extension}`;\n}\n\n/**\n * Get timestamped filename for archived audio\n */\nexport function getTimestampedArchivedAudioFilename(originalExtension: string = '.wav'): string {\n return getTimestampedFilename('review-audio', originalExtension);\n}\n\n/**\n * Get timestamped filename for archived transcript\n */\nexport function getTimestampedArchivedTranscriptFilename(): string {\n return getTimestampedFilename('review-transcript', '.md');\n}\n\n/**\n * Archive audio file with transcription to specified directory\n * This saves BOTH the audio file AND transcription text together\n * @param originalAudioPath Path to the original audio file\n * @param transcriptionText The transcribed text content\n * @param outputDirectory Directory to save archived files (default: 'output')\n * @returns Paths to both archived audio and transcript files\n */\nexport async function archiveAudio(\n originalAudioPath: string,\n transcriptionText: string,\n outputDirectory: string = 'output'\n): Promise<{ audioPath: string; transcriptPath: string }> {\n const logger = getLogger();\n const path = await import('path');\n\n try {\n // Ensure the output directory exists\n await fs.mkdir(outputDirectory, { recursive: true });\n\n // Get file extension from original audio file\n const originalExtension = path.extname(originalAudioPath);\n\n // Generate timestamped filenames\n const archivedAudioFilename = getTimestampedArchivedAudioFilename(originalExtension);\n const archivedTranscriptFilename = getTimestampedArchivedTranscriptFilename();\n\n // Full paths for archived files\n const archivedAudioPath = path.join(outputDirectory, archivedAudioFilename);\n const archivedTranscriptPath = path.join(outputDirectory, archivedTranscriptFilename);\n\n // Copy audio file if it exists\n try {\n await fs.access(originalAudioPath);\n const audioBuffer = await fs.readFile(originalAudioPath);\n await fs.writeFile(archivedAudioPath, audioBuffer);\n logger.debug('Archived audio file to: %s', archivedAudioPath);\n } catch {\n logger.warn('AUDIO_FILE_NOT_FOUND: Original audio file not accessible | Path: %s | Impact: Cannot archive original', originalAudioPath);\n }\n\n // Save transcription text\n const transcriptContent = `# Audio Transcription Archive\\n\\n**Original Audio File:** ${originalAudioPath}\\n**Archived:** ${new Date().toISOString()}\\n\\n## Transcription\\n\\n${transcriptionText}`;\n await fs.writeFile(archivedTranscriptPath, transcriptContent, 'utf8');\n logger.debug('Archived transcription to: %s', archivedTranscriptPath);\n\n logger.info('AUDIO_ARCHIVED: Audio and transcript archived successfully | Audio: %s | Transcript: %s | Status: archived', archivedAudioFilename, archivedTranscriptFilename);\n\n return {\n audioPath: archivedAudioPath,\n transcriptPath: archivedTranscriptPath\n };\n\n } catch (error: any) {\n logger.error('AUDIO_ARCHIVE_FAILED: Failed to archive audio files | Error: %s | Impact: Audio not preserved', error.message);\n throw new Error(`Audio archiving failed: ${error.message}`);\n }\n}\n\n/**\n * Delete audio file\n */\nexport async function deleteAudio(audioPath: string): Promise<void> {\n const logger = getLogger();\n\n try {\n await fs.unlink(audioPath);\n logger.debug(`Deleted audio file: ${audioPath}`);\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n logger.warn(`Failed to delete audio file: ${error}`);\n }\n }\n}\n\n/**\n * Get audio file duration (requires external library or audio analysis)\n * For now, returns null - can be enhanced later\n */\nexport async function getAudioDuration(_audioPath: string): Promise<number | null> {\n // TODO: Implement audio duration detection\n // May require additional library like 'music-metadata'\n return null;\n}\n\n","/**\n * Audio transcription utilities\n * Wraps @grunnverk/ai-service for convenience\n */\n\nimport { transcribeAudio as aiTranscribe } from '@grunnverk/ai-service';\nimport { getLogger } from '@grunnverk/shared';\n\n/**\n * Transcribe audio file using AI service\n * This is a convenience wrapper around @grunnverk/ai-service\n */\nexport async function transcribeAudio(audioPath: string): Promise<string> {\n const logger = getLogger();\n\n try {\n logger.info('Transcribing audio...');\n const result = await aiTranscribe(audioPath);\n const transcript = result.text;\n logger.info('Transcription complete');\n return transcript;\n } catch (error) {\n logger.error('Transcription failed:', error);\n throw new Error(`Transcription failed: ${error}`);\n }\n}\n\n"],"names":["ANSI","CURSOR_UP","CURSOR_TO_START","CLEAR_LINE","RED","CYAN","RESET","BOLD","formatTime","seconds","minutes","Math","floor","remainingSeconds","toString","padStart","beep","process","stdout","write","supportsAnsi","isTTY","env","TERM","NO_COLOR","CountdownTimer","start","Promise","resolve","currentSeconds","options","onComplete","displayCountdown","intervalId","setInterval","isDestroyed","clearInterval","beepAt30Seconds","hasBeepedAt30","onTick","stop","clearOnComplete","isFirstDisplay","getRemainingSeconds","timeString","isWarningTime","output","color","redAt30Seconds","style","warning","setupCleanupHandlers","NODE_ENV","VITEST","cleanup","destroy","exitHandler","uncaughtExceptionHandler","error","on","cleanupHandlers","removeListener","forEach","handler","isTimerDestroyed","durationSeconds","startCountdown","timer","createAudioRecordingCountdown","countdown","listAudioDevices","logger","getLogger","warn","getDefaultDevice","devices","find","d","isDefault","findDevice","idOrName","id","name","selectDeviceInteractive","preferencesDir","join","homedir","result","selectAndConfigureAudioDevice","Error","recordAudio","duration","outputPath","startTime","Date","now","info","audioResult","processAudio","file","undefined","maxRecordingTime","outputDirectory","substring","lastIndexOf","debug","cancelled","endTime","actualDuration","filePath","audioFilePath","stats","fs","stat","toFixed","size","fileSize","getTimestampedFilename","baseName","extension","yy","getFullYear","slice","mm","getMonth","dd","getDate","hh","getHours","min","getMinutes","timestamp","getTimestampedArchivedAudioFilename","originalExtension","getTimestampedArchivedTranscriptFilename","archiveAudio","originalAudioPath","transcriptionText","path","mkdir","recursive","extname","archivedAudioFilename","archivedTranscriptFilename","archivedAudioPath","archivedTranscriptPath","access","audioBuffer","readFile","writeFile","transcriptContent","toISOString","audioPath","transcriptPath","message","deleteAudio","unlink","code","getAudioDuration","_audioPath","transcribeAudio","aiTranscribe","transcript","text"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/countdown.ts","../src/devices.ts","../src/recording.ts","../src/transcription.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Countdown timer utility for audio recording sessions\n * Provides a visual countdown with beep warnings and color changes\n */\n\nexport interface CountdownOptions {\n /** Duration in seconds */\n durationSeconds: number;\n /** Show beep warning at 30 seconds remaining */\n beepAt30Seconds?: boolean;\n /** Change color to red at 30 seconds remaining */\n redAt30Seconds?: boolean;\n /** Callback function called every second with remaining time */\n onTick?: (remainingSeconds: number) => void;\n /** Callback function called when countdown reaches zero */\n onComplete?: () => void;\n /** Whether to clear the countdown line when finished */\n clearOnComplete?: boolean;\n}\n\n/**\n * ANSI escape codes for terminal control\n */\nconst ANSI = {\n // Cursor movement\n CURSOR_UP: '\\x1b[1A',\n CURSOR_TO_START: '\\x1b[0G',\n CLEAR_LINE: '\\x1b[2K',\n\n // Colors\n RED: '\\x1b[31m',\n GREEN: '\\x1b[32m',\n YELLOW: '\\x1b[33m',\n BLUE: '\\x1b[34m',\n MAGENTA: '\\x1b[35m',\n CYAN: '\\x1b[36m',\n WHITE: '\\x1b[37m',\n RESET: '\\x1b[0m',\n\n // Text styles\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m'\n} as const;\n\n/**\n * Format seconds into MM:SS format\n */\nfunction formatTime(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n}\n\n/**\n * Generate a beep sound using process.stdout.write with ASCII bell character\n */\nfunction beep(): void {\n process.stdout.write('\\x07'); // ASCII bell character\n}\n\n/**\n * Check if terminal supports colors and cursor movement\n */\nfunction supportsAnsi(): boolean {\n return process.stdout.isTTY &&\n process.env.TERM !== 'dumb' &&\n !process.env.NO_COLOR;\n}\n\n/**\n * Display a live countdown timer that updates in place\n */\nexport class CountdownTimer {\n private options: Required<CountdownOptions>;\n private intervalId: NodeJS.Timeout | null = null;\n private currentSeconds: number;\n private hasBeepedAt30: boolean = false;\n private isFirstDisplay: boolean = true;\n private supportsAnsi: boolean;\n private cleanupHandlers: Array<() => void> = [];\n private isDestroyed = false;\n\n constructor(options: CountdownOptions) {\n this.options = {\n beepAt30Seconds: true,\n redAt30Seconds: true,\n onTick: () => {},\n onComplete: () => {},\n clearOnComplete: false,\n ...options\n };\n this.currentSeconds = this.options.durationSeconds;\n this.supportsAnsi = supportsAnsi();\n\n // Set up cleanup handlers for process termination\n this.setupCleanupHandlers();\n }\n\n /**\n * Start the countdown timer\n */\n start(): Promise<void> {\n return new Promise((resolve) => {\n // Handle zero seconds case\n if (this.currentSeconds <= 0) {\n this.options.onComplete();\n resolve();\n return;\n }\n\n // Display initial countdown\n this.displayCountdown();\n\n this.intervalId = setInterval(() => {\n // Check if destroyed before processing\n if (this.isDestroyed) {\n clearInterval(this.intervalId!);\n resolve();\n return;\n }\n\n this.currentSeconds--;\n\n // Check for beep warning\n if (this.options.beepAt30Seconds &&\n this.currentSeconds === 30 &&\n !this.hasBeepedAt30) {\n beep();\n this.hasBeepedAt30 = true;\n }\n\n // Call tick callback\n this.options.onTick(this.currentSeconds);\n\n if (this.currentSeconds <= 0) {\n this.stop();\n this.options.onComplete();\n resolve();\n } else {\n this.displayCountdown();\n }\n }, 1000);\n });\n }\n\n /**\n * Stop the countdown timer\n */\n stop(): void {\n if (this.isDestroyed) {\n return;\n }\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (this.options.clearOnComplete && this.supportsAnsi) {\n // Clear the countdown line\n process.stdout.write(ANSI.CURSOR_TO_START + ANSI.CLEAR_LINE);\n } else if (!this.isFirstDisplay) {\n // Add a newline if we've been updating in place\n process.stdout.write('\\n');\n }\n }\n\n /**\n * Get current remaining time\n */\n getRemainingSeconds(): number {\n return this.currentSeconds;\n }\n\n /**\n * Display the countdown timer\n */\n private displayCountdown(): void {\n const timeString = formatTime(this.currentSeconds);\n const isWarningTime = this.currentSeconds <= 30;\n\n let output: string;\n\n if (this.supportsAnsi) {\n // Use colors and in-place updating if supported\n if (!this.isFirstDisplay) {\n // Move cursor up and clear the line to overwrite previous countdown\n process.stdout.write(ANSI.CURSOR_UP + ANSI.CURSOR_TO_START + ANSI.CLEAR_LINE);\n }\n\n const color = isWarningTime && this.options.redAt30Seconds ? ANSI.RED : ANSI.CYAN;\n const style = isWarningTime ? ANSI.BOLD : '';\n\n output = `${color}${style}⏱️ Recording time remaining: ${timeString}${ANSI.RESET}`;\n } else {\n // Fallback for terminals that don't support ANSI\n const warning = isWarningTime ? ' ⚠️ ' : '';\n output = `⏱️ Recording time remaining: ${timeString}${warning}`;\n }\n\n process.stdout.write(output + '\\n');\n this.isFirstDisplay = false;\n }\n\n /**\n * Set up cleanup handlers for process termination and uncaught exceptions\n */\n private setupCleanupHandlers(): void {\n // Skip setting up process listeners in test environments to avoid listener leaks\n if (process.env.NODE_ENV === 'test' || process.env.VITEST) {\n return;\n }\n\n const cleanup = () => {\n this.destroy();\n };\n\n // Handle various exit scenarios\n const exitHandler = () => cleanup();\n const uncaughtExceptionHandler = (error: Error) => {\n cleanup();\n // Re-throw to maintain normal error handling\n throw error;\n };\n\n process.on('exit', exitHandler);\n process.on('SIGINT', exitHandler);\n process.on('SIGTERM', exitHandler);\n process.on('uncaughtException', uncaughtExceptionHandler);\n process.on('unhandledRejection', cleanup);\n\n // Store handlers for removal during destroy\n this.cleanupHandlers = [\n () => process.removeListener('exit', exitHandler),\n () => process.removeListener('SIGINT', exitHandler),\n () => process.removeListener('SIGTERM', exitHandler),\n () => process.removeListener('uncaughtException', uncaughtExceptionHandler),\n () => process.removeListener('unhandledRejection', cleanup)\n ];\n }\n\n /**\n * Destroy the timer and clean up all resources\n */\n destroy(): void {\n if (this.isDestroyed) {\n return;\n }\n\n this.isDestroyed = true;\n this.stop();\n\n // Remove all process event listeners\n this.cleanupHandlers.forEach(handler => {\n try {\n handler();\n } catch {\n // Ignore errors during cleanup\n }\n });\n this.cleanupHandlers = [];\n }\n\n /**\n * Check if the timer has been destroyed\n */\n isTimerDestroyed(): boolean {\n return this.isDestroyed;\n }\n}\n\n/**\n * Create and start a countdown timer (convenience function)\n */\nexport async function startCountdown(options: CountdownOptions): Promise<void> {\n const timer = new CountdownTimer(options);\n return timer.start();\n}\n\n/**\n * Create a countdown timer for audio recording with sensible defaults\n */\nexport function createAudioRecordingCountdown(durationSeconds: number): CountdownTimer {\n return new CountdownTimer({\n durationSeconds,\n beepAt30Seconds: true,\n redAt30Seconds: true,\n clearOnComplete: true\n });\n}\n\n/**\n * Simple countdown function for backwards compatibility\n * @param seconds Number of seconds to count down\n * @param onTick Optional callback called on each tick\n * @deprecated Use CountdownTimer or startCountdown for more features\n */\nexport async function countdown(\n seconds: number,\n onTick?: (remaining: number) => void\n): Promise<void> {\n const options: CountdownOptions = {\n durationSeconds: seconds,\n beepAt30Seconds: false,\n redAt30Seconds: false,\n clearOnComplete: false\n };\n\n if (onTick) {\n options.onTick = onTick;\n }\n\n await startCountdown(options);\n}\n","/**\n * Audio device detection and selection\n */\n\nimport { selectAndConfigureAudioDevice } from '@utilarium/unplayable';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { getLogger } from '@grunnverk/shared';\nimport type { AudioDevice } from './types';\n\n/**\n * List all available audio input devices\n * Note: This is a placeholder - @utilarium/unplayable doesn't provide a direct API for this\n * In practice, you would use selectAndConfigureAudioDevice for device selection\n */\nexport async function listAudioDevices(): Promise<AudioDevice[]> {\n const logger = getLogger();\n\n // This would require extending @utilarium/unplayable or using a different library\n logger.warn('listAudioDevices is not fully implemented - use selectDeviceInteractive instead');\n return [];\n}\n\n/**\n * Get the default audio input device\n */\nexport async function getDefaultDevice(): Promise<AudioDevice | null> {\n const devices = await listAudioDevices();\n return devices.find((d) => d.isDefault) || devices[0] || null;\n}\n\n/**\n * Find device by ID or name\n */\nexport async function findDevice(idOrName: string): Promise<AudioDevice | null> {\n const devices = await listAudioDevices();\n\n return (\n devices.find((d) => d.id === idOrName) ||\n devices.find((d) => d.name === idOrName) ||\n null\n );\n}\n\n/**\n * Interactive device selection using @utilarium/unplayable\n * This function uses the built-in interactive device selector\n */\nexport async function selectDeviceInteractive(): Promise<string> {\n const logger = getLogger();\n\n try {\n const preferencesDir = join(homedir(), '.unplayable');\n const result = await selectAndConfigureAudioDevice(preferencesDir, logger, false);\n return result;\n } catch (error) {\n logger.error('Device selection failed:', error);\n throw new Error(`Device selection failed: ${error}`);\n }\n}\n\n","/**\n * Audio recording functionality\n */\n\nimport { processAudio } from '@utilarium/unplayable';\nimport { promises as fs } from 'fs';\nimport { join } from 'path';\nimport { getLogger } from '@grunnverk/shared';\nimport type { RecordingOptions, RecordingResult } from './types';\n\n/**\n * Record audio using @utilarium/unplayable\n */\nexport async function recordAudio(\n options: RecordingOptions = {}\n): Promise<RecordingResult> {\n const logger = getLogger();\n\n const {\n duration,\n outputPath,\n } = options;\n\n const startTime = Date.now();\n\n try {\n logger.info('Starting audio recording...');\n logger.info('Press ENTER to stop recording');\n\n const audioResult = await processAudio({\n file: undefined,\n maxRecordingTime: duration,\n outputDirectory: outputPath ? outputPath.substring(0, outputPath.lastIndexOf('/')) : 'output',\n debug: false\n });\n\n if (audioResult.cancelled) {\n throw new Error('Recording cancelled by user');\n }\n\n const endTime = Date.now();\n const actualDuration = (endTime - startTime) / 1000;\n\n // Get file stats\n const filePath = audioResult.audioFilePath || join('output', `recording-${Date.now()}.wav`);\n const stats = await fs.stat(filePath);\n\n logger.info(`Recording complete: ${filePath}`);\n logger.info(`Duration: ${actualDuration.toFixed(2)} seconds`);\n logger.info(`File size: ${(stats.size / 1024).toFixed(2)} KB`);\n\n return {\n filePath,\n duration: actualDuration,\n fileSize: stats.size,\n };\n } catch (error) {\n logger.error('Recording failed:', error);\n throw new Error(`Recording failed: ${error}`);\n }\n}\n\n/**\n * Get timestamped filename for archiving\n */\nfunction getTimestampedFilename(baseName: string, extension: string = '.json'): string {\n const now = new Date();\n\n // Format as YYMMdd-HHmm (e.g., 250701-1030)\n const yy = now.getFullYear().toString().slice(-2);\n const mm = (now.getMonth() + 1).toString().padStart(2, '0');\n const dd = now.getDate().toString().padStart(2, '0');\n const hh = now.getHours().toString().padStart(2, '0');\n const min = now.getMinutes().toString().padStart(2, '0');\n\n const timestamp = `${yy}${mm}${dd}-${hh}${min}`;\n\n return `${timestamp}-${baseName}${extension}`;\n}\n\n/**\n * Get timestamped filename for archived audio\n */\nexport function getTimestampedArchivedAudioFilename(originalExtension: string = '.wav'): string {\n return getTimestampedFilename('review-audio', originalExtension);\n}\n\n/**\n * Get timestamped filename for archived transcript\n */\nexport function getTimestampedArchivedTranscriptFilename(): string {\n return getTimestampedFilename('review-transcript', '.md');\n}\n\n/**\n * Archive audio file with transcription to specified directory\n * This saves BOTH the audio file AND transcription text together\n * @param originalAudioPath Path to the original audio file\n * @param transcriptionText The transcribed text content\n * @param outputDirectory Directory to save archived files (default: 'output')\n * @returns Paths to both archived audio and transcript files\n */\nexport async function archiveAudio(\n originalAudioPath: string,\n transcriptionText: string,\n outputDirectory: string = 'output'\n): Promise<{ audioPath: string; transcriptPath: string }> {\n const logger = getLogger();\n const path = await import('path');\n\n try {\n // Ensure the output directory exists\n await fs.mkdir(outputDirectory, { recursive: true });\n\n // Get file extension from original audio file\n const originalExtension = path.extname(originalAudioPath);\n\n // Generate timestamped filenames\n const archivedAudioFilename = getTimestampedArchivedAudioFilename(originalExtension);\n const archivedTranscriptFilename = getTimestampedArchivedTranscriptFilename();\n\n // Full paths for archived files\n const archivedAudioPath = path.join(outputDirectory, archivedAudioFilename);\n const archivedTranscriptPath = path.join(outputDirectory, archivedTranscriptFilename);\n\n // Copy audio file if it exists\n try {\n await fs.access(originalAudioPath);\n const audioBuffer = await fs.readFile(originalAudioPath);\n await fs.writeFile(archivedAudioPath, audioBuffer);\n logger.debug('Archived audio file to: %s', archivedAudioPath);\n } catch {\n logger.warn('AUDIO_FILE_NOT_FOUND: Original audio file not accessible | Path: %s | Impact: Cannot archive original', originalAudioPath);\n }\n\n // Save transcription text\n const transcriptContent = `# Audio Transcription Archive\\n\\n**Original Audio File:** ${originalAudioPath}\\n**Archived:** ${new Date().toISOString()}\\n\\n## Transcription\\n\\n${transcriptionText}`;\n await fs.writeFile(archivedTranscriptPath, transcriptContent, 'utf8');\n logger.debug('Archived transcription to: %s', archivedTranscriptPath);\n\n logger.info('AUDIO_ARCHIVED: Audio and transcript archived successfully | Audio: %s | Transcript: %s | Status: archived', archivedAudioFilename, archivedTranscriptFilename);\n\n return {\n audioPath: archivedAudioPath,\n transcriptPath: archivedTranscriptPath\n };\n\n } catch (error: any) {\n logger.error('AUDIO_ARCHIVE_FAILED: Failed to archive audio files | Error: %s | Impact: Audio not preserved', error.message);\n throw new Error(`Audio archiving failed: ${error.message}`);\n }\n}\n\n/**\n * Delete audio file\n */\nexport async function deleteAudio(audioPath: string): Promise<void> {\n const logger = getLogger();\n\n try {\n await fs.unlink(audioPath);\n logger.debug(`Deleted audio file: ${audioPath}`);\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n logger.warn(`Failed to delete audio file: ${error}`);\n }\n }\n}\n\n/**\n * Get audio file duration (requires external library or audio analysis)\n * For now, returns null - can be enhanced later\n */\nexport async function getAudioDuration(_audioPath: string): Promise<number | null> {\n // TODO: Implement audio duration detection\n // May require additional library like 'music-metadata'\n return null;\n}\n\n","/**\n * Audio transcription utilities\n * Wraps @grunnverk/ai-service for convenience\n */\n\nimport { transcribeAudio as aiTranscribe } from '@grunnverk/ai-service';\nimport { getLogger } from '@grunnverk/shared';\n\n/**\n * Transcribe audio file using AI service\n * This is a convenience wrapper around @grunnverk/ai-service\n */\nexport async function transcribeAudio(audioPath: string): Promise<string> {\n const logger = getLogger();\n\n try {\n logger.info('Transcribing audio...');\n const result = await aiTranscribe(audioPath);\n const transcript = result.text;\n logger.info('Transcription complete');\n return transcript;\n } catch (error) {\n logger.error('Transcription failed:', error);\n throw new Error(`Transcription failed: ${error}`);\n }\n}\n\n"],"names":["ANSI","CURSOR_UP","CURSOR_TO_START","CLEAR_LINE","RED","CYAN","RESET","BOLD","formatTime","seconds","minutes","Math","floor","remainingSeconds","toString","padStart","beep","process","stdout","write","supportsAnsi","isTTY","env","TERM","NO_COLOR","CountdownTimer","start","Promise","resolve","currentSeconds","options","onComplete","displayCountdown","intervalId","setInterval","isDestroyed","clearInterval","beepAt30Seconds","hasBeepedAt30","onTick","stop","clearOnComplete","isFirstDisplay","getRemainingSeconds","timeString","isWarningTime","output","color","redAt30Seconds","style","warning","setupCleanupHandlers","NODE_ENV","VITEST","cleanup","destroy","exitHandler","uncaughtExceptionHandler","error","on","cleanupHandlers","removeListener","forEach","handler","isTimerDestroyed","durationSeconds","startCountdown","timer","createAudioRecordingCountdown","countdown","listAudioDevices","logger","getLogger","warn","getDefaultDevice","devices","find","d","isDefault","findDevice","idOrName","id","name","selectDeviceInteractive","preferencesDir","join","homedir","result","selectAndConfigureAudioDevice","Error","recordAudio","duration","outputPath","startTime","Date","now","info","audioResult","processAudio","file","undefined","maxRecordingTime","outputDirectory","substring","lastIndexOf","debug","cancelled","endTime","actualDuration","filePath","audioFilePath","stats","fs","stat","toFixed","size","fileSize","getTimestampedFilename","baseName","extension","yy","getFullYear","slice","mm","getMonth","dd","getDate","hh","getHours","min","getMinutes","timestamp","getTimestampedArchivedAudioFilename","originalExtension","getTimestampedArchivedTranscriptFilename","archiveAudio","originalAudioPath","transcriptionText","path","mkdir","recursive","extname","archivedAudioFilename","archivedTranscriptFilename","archivedAudioPath","archivedTranscriptPath","access","audioBuffer","readFile","writeFile","transcriptContent","toISOString","audioPath","transcriptPath","message","deleteAudio","unlink","code","getAudioDuration","_audioPath","transcribeAudio","aiTranscribe","transcript","text"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { AudioDevice } from './types';
2
2
  /**
3
3
  * List all available audio input devices
4
- * Note: This is a placeholder - @theunwalked/unplayable doesn't provide a direct API for this
4
+ * Note: This is a placeholder - @utilarium/unplayable doesn't provide a direct API for this
5
5
  * In practice, you would use selectAndConfigureAudioDevice for device selection
6
6
  */
7
7
  export declare function listAudioDevices(): Promise<AudioDevice[]>;
@@ -14,7 +14,7 @@ export declare function getDefaultDevice(): Promise<AudioDevice | null>;
14
14
  */
15
15
  export declare function findDevice(idOrName: string): Promise<AudioDevice | null>;
16
16
  /**
17
- * Interactive device selection using @theunwalked/unplayable
17
+ * Interactive device selection using @utilarium/unplayable
18
18
  * This function uses the built-in interactive device selector
19
19
  */
20
20
  export declare function selectDeviceInteractive(): Promise<string>;
@@ -1,6 +1,6 @@
1
1
  import { RecordingOptions, RecordingResult } from './types';
2
2
  /**
3
- * Record audio using @theunwalked/unplayable
3
+ * Record audio using @utilarium/unplayable
4
4
  */
5
5
  export declare function recordAudio(options?: RecordingOptions): Promise<RecordingResult>;
6
6
  /**
package/guide/index.md CHANGED
@@ -34,7 +34,7 @@ const text = await transcribe(audioFile);
34
34
  ## Dependencies
35
35
 
36
36
  - @grunnverk/ai-service - Transcription via OpenAI
37
- - @theunwalked/unplayable - Audio recording engine
37
+ - @utilarium/unplayable - Audio recording engine
38
38
 
39
39
  ## Package Structure
40
40
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grunnverk/audio-tools",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "Audio recording tools for voice-driven development workflows",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -41,7 +41,7 @@
41
41
  "license": "Apache-2.0",
42
42
  "dependencies": {
43
43
  "@grunnverk/ai-service": "^1.5.3",
44
- "@theunwalked/unplayable": "^0.0.28"
44
+ "@utilarium/unplayable": "^0.0.29"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@grunnverk/shared": "^1.5.4",