85bfdf2b56107c24c6572d8d48e805cf30e7382a
New 'Recap' phase — turns speakers.json into a human-readable recap, leveraging recap-relay's proven logic/prompts but calling the Spark gateway's OpenAI-compatible /v1/chat/completions directly (same host/TLS as label-merge; Qwen3-35B). We start from already-named speakers (label-merge), so recap-relay's speaker clustering + name-inference are skipped entirely. - GatewayLLMClient: /v1/chat/completions (JSON mode), model discovery via /api/endpoints, TLS-skip reuse, 503 retry, sequential. - RecapAnalyzer: speakers.json → numbered [N] (MM:SS) Name: text transcript → time-windowed analyze (single window for short calls, 18min/2min overlap for long) → stitch/dedup topic sections → meeting extras (TLDR/decisions/action_items/ open_questions/key_quotes). Defensive JSON parsing of LLM output. - RecapRenderer: writes transcript.md + a self-contained dark-theme recap.html (topic sections w/ collapsible transcripts, extras panels, speaker color chips, full timestamped speaker-attributed transcript, print styles). - SessionController.buildRecap: best-effort after speakers.json (gated by settings.recapEnabled); surfaces recapURL → menu 'Open recap'. Skips silently if the gateway has no LLM. Settings toggle added. Validated END-TO-END on the real Meet session against the live gateway: dual-channel transcription → 3 topic sections + accurate TLDR + key quotes; 'Go Bitcoin' correctly attributed to the remote speaker. 46/46 XCTest (10 new).
Ten31 Transcripts
Native macOS menu-bar app that auto-detects conference calls, records local audio,
builds a visual-derived speaker timeline, and hands audio + timeline to the
SparkControl backend for naming/transcription. See docs/ for the full spec.
This repo is at Phase 0 (scaffold, permissions, backend health check).
One-time setup
- Install Xcode from the Mac App Store (free; ~40 GB). Open it once and accept the license prompt.
- Install XcodeGen (generates the Xcode project from
project.yml):brew install xcodegen - Generate the project:
This creates
xcodegen generateTen31Transcripts.xcodeproj(git-ignored — regenerate any time). - Open it:
open Ten31Transcripts.xcodeproj - Signing is preconfigured:
project.ymlsetsDEVELOPMENT_TEAMto the free personal teamBK4Y6CXN35with automatic signing, so Signing & Capabilities should already show the team — no manual selection needed. (If you ever sign with a different Apple ID, updateDEVELOPMENT_TEAMinproject.yml, not in Xcode —xcodegen generateoverwrites Xcode-side changes.) - Press Run (⌘R).
Note: after adding files in a new phase, re-run
xcodegen generateand let Xcode reload the project. The signing team persists because it lives inproject.yml, so macOS permissions stay granted across rebuilds.
What Phase 0 does
- Launches as a menu-bar-only app (no Dock icon).
- Menu panel shows live status for the three permissions it needs — Microphone, Screen Recording, Accessibility — with Grant / Open Settings buttons.
- Shows a backend health check (
GET /api/status) against the configured host. - Settings: backend base URL, skip-TLS toggle (on by default for the self-signed cert), output folder, and adapter toggles (inert this phase).
No audio capture, call detection, screen reading, or backend hand-off yet — those
arrive in Phases 1–6 (docs/04_BUILD_PLAN.md).
Project layout
project.yml # XcodeGen recipe → generates the .xcodeproj
Ten31Transcripts/
App/ Ten31TranscriptsApp.swift, AppDelegate.swift
UI/ MenuBarView, SettingsView, PermissionRow
Permissions/PermissionsManager.swift
Backend/ SparkControlHealth.swift, InsecureTrustDelegate.swift
Settings/ AppSettings.swift
Support/ Info.plist, Ten31Transcripts.entitlements
Ten31TranscriptsTests/ # placeholder; real tests land in Phase 3
Notes
- App Sandbox is off and Hardened Runtime is off — this is a personal, LAN-only tool that must observe other apps. Revisit only if distributing.
- The default backend host is
https://your-spark-backend.local:62419(editable in Settings).
Description
Languages
Swift
100%