Recap editor: Regenerate recap (re-run LLM on corrected transcript)

Adds a 'Regenerate recap' action so corrected speaker names flow into freshly
written summaries/extras (not just find-replaced). regenerate() commits the
corrections (rewrite speakers.json + reconcile voiceprints), re-runs RecapAnalyzer
on the corrected transcript via the gateway LLM, and rewrites recap.json +
transcript.md + recap.html. save() and regenerate() share commitCorrections();
both rebaseline the speaker set afterward so further edits map cleanly. Editor view
gains the button + progress spinner; RecapEditModel takes the gateway baseURL/skipTLS.

52/52 XCTest; builds clean.
This commit is contained in:
Grant Gilliam
2026-06-06 16:48:18 -05:00
parent 4c086251d9
commit 10ddf9992a
4 changed files with 76 additions and 18 deletions
@@ -94,11 +94,15 @@ struct TranscriptEditorView: View {
// MARK: - Footer
private var footer: some View {
HStack {
HStack(spacing: 10) {
Button("Save corrections") { model.save() }
.keyboardShortcut("s", modifiers: .command)
.disabled(!model.dirty)
if let s = model.status { Text(s).font(.caption).foregroundStyle(.green) }
.disabled(!model.dirty || model.regenerating)
Button("Regenerate recap") { Task { await model.regenerate() } }
.help("Re-run the analysis on the corrected transcript so summaries use the fixed names.")
.disabled(model.regenerating)
if model.regenerating { ProgressView().controlSize(.small) }
if let s = model.status { Text(s).font(.caption).foregroundStyle(.secondary) }
Spacer()
if let recap = recapURL {
Button("Open recap") { NSWorkspace.shared.open(recap) }