zgba Network

Scripta 3.4.7: schedule local meeting recordings without sending anything to the cloud

Follow-up to Building a 100% local meeting transcription app for macOS — Scripta already records dual-channel audio and summarizes with a local LLM. v3.4.7 adds something I kept forgetting to do myself: **hit Record before the meeting starts. The problem Scripta works great when I remember to open it and tap Start Recording. I do not always remember. Recurring standups, interviews, and “just a quick sync” calls all have a start time on the calendar — but my muscle memory does not. Cloud assistants solve this by running in someone else’s datacenter. Scripta’s whole pitch is nothing leaves the Mac, so “schedule a bot in the cloud” was never an option. What I wanted instead: Name the meeting (“Product sync”, not 2026-09-25_16-50-00) Pick start and end (or start + duration) Let the app start and stop capture while it is running Keep transcripts and metadata local, same as manual recording That shipped in Scripta v3.4.7. What it looks like Open Scheduled Recordings from the toolbar calendar icon (or the menu bar): Create a meeting — title, window, language, optional notification if the app is not open at start time: Upcoming items show status (Pending, Recording now, Waiting to start, etc.) with Edit, Cancel, or Stop recording when relevant: When a scheduled session finishes, the export folder’s session.json includes a title and optional scheduledRecordingId, so Meeting History is searchable by name. Product rules we locked in These are intentional — not missing features for v3.5: Rule Why No overlapping schedules Saves fail validation if windows intersect No auto-summary after scheduled stop Manual recordings still offer the summary sheet when Ollama is ready; scheduled runs set suppressAutoSummary so you are not interrupted No takeover without consent If you are already recording at start time, Scripta asks whether to stop the current session and start the scheduled one App must be running for auto-capture Phase 1 is in-process scheduling only — no launchd daemon silently recording in the background If the app is closed at start time A local notification nudges you to open Scripta; it does not pretend recording happened Calendar import, multi-device sync, and “record with zero UI process” are explicitly later phases. How it works (implementation sketch) Persistence is a single JSON file: ~/Library/Application Support/Scripta/schedules.json A ScheduleCoordinator ticks about once per second while the app runs: Arm 5-minute local notifications for upcoming items At start → configure the recorder (title, language, no summary popup), then startRecording() if permissions are already granted At end → stopRecording() for that schedule’s session Reconcile stale states after quit/reopen (e.g. JSON said “recording” but capture never started) Before auto-start, ScreenRecordingAccess checks mic, speech, and ScreenCaptureKit — scheduled paths avoid hammering the system permission dialog every second if you forgot to grant Screen Recording. Recording still uses the same pipeline as manual mode: whisper.cpp on the mic, SFSpeechRecognizer on system audio via ScreenCaptureKit (architecture write-up). Optional Awake (bottom bar, default on): while recording or finishing transcription, Scripta holds an NSProcessInfo activity to prevent idle system and display sleep — not a guarantee against lid-close or manual sleep, but enough for long calls at your desk. Permissions: the real UX tax The scheduler did not create new TCC categories — it surfaced the same ones as manual record: Microphone Screen Recording (required for system audio, even though we only capture audio) Speech Recognition Run Permissions Setup once before the meeting window. If auto-start fails, the list shows Waiting to start with Retry start after you fix settings and return to the app. If you develop from source, install to /Applications/Scripta.app (scripts/install-local.sh) so TCC matches what users run in production. swift run binaries are a different story. What we learned shipping it Do not flip @Published language on a background thread when auto-starting — SwiftUI will punish you with stack overflows in Release builds. Do not mark a schedule “recording” until MeetingRecorder actually enters .recording — quitting during a permission prompt left JSON lying. README type-checker limits are real — splitting ContentView lifecycle modifiers into smaller views fixed macOS 15 CI. Try it Install (macOS 14+, Apple Silicon or Intel): curl -fsSL https://raw.githubusercontent.com/thehwang/Scripta/main/scripts/install.sh | bash Repo: github.com/thehwang/Scripta After install: complete Permissions Setup, open Scheduled Recordings, add a meeting a few minutes ahead, leave Scripta open, and watch it start on its own. If this fits your workflow, a GitHub star helps others find it. Issues and PRs welcome — especially around calendar import and safer wake-from-sleep behavior. Scripta is MIT-licensed. Scheduled recording is local-only: your schedules live in schedules.json on disk, not on our servers — because there are no servers.

View original article