Repository navigation
Click a transcript timestamp to play the meeting from there - #1772
Conversation
Clicking a row's time in the opened meeting now plays the saved audio from that moment. It seeks the loaded audio (keeping the chosen source) or starts this meeting's audio there. Meetings with no saved audio keep plain, non-clickable times. Transcript paragraph splitting is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm
Review follow-ups for clickable timestamps: - Move the player's idle source pick into MeetingAudioPlayback so a timestamp click plays the source the menu shows (Mic stays Mic). - A click past the end of the loaded source beeps instead of finishing instantly and resetting the player. - Re-apply the start position after NSSound.play() so a fresh start from a timestamp can't rewind to zero. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm
- AGENTS.md and Sources/UI/CLAUDE.md no longer say transcript rows are static; rows still never follow the playhead. - Cover 3-digit minutes (125:30), which the transcript writer emits for meetings past 100 minutes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm
Ported from #1785 (9faf88d): the Core package tests stalled on this PR (CoreAudioSystemAudioCaptureTests, XCTest stall detector), and #1785 identifies this test as the likeliest cause. It never created its temp root, so start() went on to probe real microphones and TCC. (cherry picked from commit 9faf88d) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm
|
It's the same intermittent Core test stall that #1785 is chasing. I ported #1785's suspected fix (9faf88d, test-only: Generated by Claude Code |
Deep review follow-ups for clickable timestamps: - S1: right after a meeting saves (or if its Mix failed) the audio is split Mic/System and System is the default, so clicking a You row played System. With no user pick, a row click now plays its own channel's track. The Mix, a single recording, or a user pick still win. - M1: remember the picked source by file stem, keyed by the meeting's audio folder, so it survives the Home rescan after recompression. - M3: per-row timestamp accessibility identifiers. - M4: seek() re-applies the time after play(), like the start path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm
|
This isn't this PR's failure. That test covers the dictation engine's AUHAL binding intent, which this PR doesn't touch (Home UI, meeting playback, docs). The same test and the same Parakeet code passed on this PR's previous head daba6f1. The assertion is a wall-clock bound: a 50 ms native timeout has to return within 200 ms of I found no existing fix. Proposed patch, kept out of this PR: raise that bound to something like Generated by Claude Code |
The wedged-setter check allowed 200ms for a 50ms budget and went red on a loaded runner (#1772). Allow 1s; a handler that is never released still fails. The success case had the same shape: a 40ms sleep that overran its 250ms budget would time the setter out first. Give it a 5s budget and require a wake well before it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RJaM9jijGY2JYUhL6GsS9Z
…stamps-y7tfkj # Conflicts: # Tests/TranscriptedCoreTests/AudioTests/AudioInitializationTests.swift
Requested by Justin · project thread
Before: an opened meeting's transcript shows a time on each row, but it's just text. To hear that moment you had to hit play and drag the scrubber around to find it.
After: click a row's time and the meeting audio plays from that moment. Hovering the time underlines it and the tooltip says "Play from 0:42". Meetings with no saved audio keep plain, non-clickable times. Rows still never highlight or follow the playhead.
How:
QuietMeetingExpansionwraps each row time in a small button when the meeting has audio and the time parses. The button callsMeetingAudioPlayback.play(_:from:rowSourceStem:). If this meeting's audio is loaded, it seeks and resumes if paused. Otherwise it starts this meeting's audio at that spot. A click past the end of the loaded file beeps and leaves playback alone. The source is picked in this order: the user's pick in the player menu, then (only while a meeting still has split Mic/System files and no Mix, e.g. right after it saves) the clicked row's own track, so a "You" row plays your mic. Otherwise it uses the default (the Mix or single recording). The player's source pick now lives inMeetingAudioPlayback, keyed by the meeting's audio folder and file stem, so it survives Home rescans. Time parsing (M:SS, including 3-digit minutes, andH:MM:SS) is a small pure helper onHomeMeetingTranscriptLine.Why
User feedback (via email): transcripts have times in them, but the times don't link to the audio.
Product Impact
meetingsmeeting reliabilityWhat changed
Sources/UI/Settings/QuietHomeLibrary.swift: clickableQuietTranscriptTimestamp(per-row accessibility id) for rows in meetings with saved audio.Sources/UI/Shared/MeetingAudioPlayback.swift:play(_:from:rowSourceStem:), picked-source memory, past-end guard, start position re-applied afterNSSound.play()in both the start and seek paths;MeetingAudioPlaybackLoadingPolicy.rowChoice/choice(in:sourceStem:).Sources/UI/Settings/HomeMeetingAudioPlayer.swift: the player's source menu reads and writes the shared pick instead of view-local state.Sources/UI/Settings/HomeMeetingPreviewFormatter.swift:HomeMeetingTranscriptLine.startSeconds+HomeMeetingTranscriptClock.seconds(from:).HomeMeetingPreviewFormatterTests), row-source choice (MeetingAudioArchiveResolverTests).AGENTS.md"keep these surfaces" line andSources/UI/CLAUDE.mdnow say row times are clickable (rows still don't follow the playhead). Flagging the AGENTS.md line for sign-off at merge.AudioInitializationTestsno longer probes real mics/TCC. It's the likely cause of the intermittent Core test stall that hit this PR's CI once. Identical to Fix the Core test freeze and a Parakeet timing flake, and capture stacks in CI #1785's version, so it no-ops when that merges.Transcript paragraph splitting is untouched (the feedback explicitly asked to keep it). No audio capture code is touched.
How I checked it
scripts/dev/agent-preflight.shbash build.sh --no-open/bash run-tests.shvia GitHub Actions CI (no macOS toolchain in this session)clickable-timestamps/mac-test-after-1.1.62.mdRisk Review
.agent-review/visuals/evidence (no Mac in this session)Notes
Each playback source is a single file (Mix, Recording, System or Mic), so only one file plays at a time. Mic vs System picking only matters in the short window after a meeting saves, before its Mix is written, or when writing the Mix failed.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VGTtv8jq8HdgQtKY9PvCcm