Skip to content

refactor: convert audiotap from CLI to in-process library#23

Merged
pasrom merged 3 commits intomainfrom
refactor/audiotap-library
Mar 15, 2026
Merged

refactor: convert audiotap from CLI to in-process library#23
pasrom merged 3 commits intomainfrom
refactor/audiotap-library

Conversation

@pasrom
Copy link
Copy Markdown
Owner

@pasrom pasrom commented Mar 15, 2026

Summary

  • Convert tools/audiotap/ from CLI executable to SPM library (AudioTapLib)
  • DualSourceRecorder uses AudioCaptureSession directly — no subprocess, no PID files, no stderr parsing
  • Enables Mac App Store distribution (no external binaries)

Changes

  • Commit 1: Split main.swift into 5 focused modules (AppAudioCapture, MicCaptureHandler, AudioCaptureSession, AudioCaptureResult, Helpers). fputsos.log, Thread.sleepasyncAfter, file handle leak guard, re-entrant restart guard.
  • Commit 2: Rewrite DualSourceRecorder to use AudioTapLib. Remove findAudiotap(), killOrphanedAudiotap(), PID file, Process/Pipe/SIGTERM handling. Remove RecorderError.audiotapNotFound, add .unsupportedOS.
  • Commit 3: Delete build_audiotap.sh, remove audiotap build/copy/sign steps from build_release.sh, update all docs.

Test plan

  • swift build — AudioTapLib compiles
  • swift build — App compiles with AudioTapLib dependency
  • swift test — 491 tests pass, 0 failures
  • ./scripts/lint.sh — No new violations
  • E2E: run_app.sh → meeting-simulator → recording → transcription → protocol generated

@github-actions github-actions bot added the chore Maintenance or non-functional changes label Mar 15, 2026
Split main.swift into focused modules:
- AppAudioCapture: CATapDescription + IOProc → FileHandle
- MicCaptureHandler: AVAudioEngine → WAV
- AudioCaptureSession: orchestrator (start/stop, computes micDelay)
- AudioCaptureResult: result struct
- Helpers: machTicksToSeconds, getDefaultOutputDeviceUID, writeAllToFileHandle

Key changes:
- Package.swift: executableTarget → library product (AudioTapLib)
- writeAllToStdout → writeAllToFileHandle (generic file descriptor)
- fputs(stderr) → os.log Logger
- Thread.sleep in device change handler → DispatchQueue.main.asyncAfter
- All public API types/methods marked public
- File handle closed on capture failure (prevents fd leak)
- Re-entrant device change guard (isRestarting flag)

This enables the Mac App Store distribution path by removing the
subprocess dependency. The host app imports AudioTapLib directly.
@pasrom pasrom force-pushed the refactor/audiotap-library branch from 8d1b725 to 4ba7bd8 Compare March 15, 2026 16:33
pasrom added 2 commits March 15, 2026 17:43
Replace subprocess-based audiotap invocation with direct AudioTapLib
library calls. DualSourceRecorder now uses AudioCaptureSession directly,
eliminating Process/Pipe management, PID file handling, and stderr
parsing. Remove findProjectRoot() from Permissions (only caller was
the removed findAudiotap()).
Remove build_audiotap.sh (no longer needed). Remove audiotap binary
build step, bundle copy, and code signing from build_release.sh.
Update CLAUDE.md, README, CONTRIBUTING, and architecture docs to
reflect AudioTapLib as a library dependency instead of CLI tool.
@pasrom pasrom force-pushed the refactor/audiotap-library branch 3 times, most recently from 063a547 to a5f8ed9 Compare March 15, 2026 19:17
@pasrom pasrom merged commit bdb1f79 into main Mar 15, 2026
8 checks passed
@pasrom pasrom deleted the refactor/audiotap-library branch March 15, 2026 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance or non-functional changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant