Grant Gilliam 85bfdf2b56 Recap: readable transcript + topic sections + meeting extras (gateway LLM)
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).
2026-06-06 14:36:18 -05:00

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

  1. Install Xcode from the Mac App Store (free; ~40 GB). Open it once and accept the license prompt.
  2. Install XcodeGen (generates the Xcode project from project.yml):
    brew install xcodegen
    
  3. Generate the project:
    xcodegen generate
    
    This creates Ten31Transcripts.xcodeproj (git-ignored — regenerate any time).
  4. Open it:
    open Ten31Transcripts.xcodeproj
    
  5. Signing is preconfigured: project.yml sets DEVELOPMENT_TEAM to the free personal team BK4Y6CXN35 with automatic signing, so Signing & Capabilities should already show the team — no manual selection needed. (If you ever sign with a different Apple ID, update DEVELOPMENT_TEAM in project.yml, not in Xcode — xcodegen generate overwrites Xcode-side changes.)
  6. Press Run (⌘R).

Note: after adding files in a new phase, re-run xcodegen generate and let Xcode reload the project. The signing team persists because it lives in project.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 16 (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).
S
Description
No description provided
Readme 890 KiB
Languages
Swift 100%