Conversation
…ring, + button hit targets
…ContentView conflict)
… + neutral color)
…roken drag-and-drop)
…lView and ThreadPickerRow to pbxproj
…TapGesture instead of nested Button
…r, vertical color list with names
…m path, not just legacy tabs
…migration from flat filters
…rid with status bars
…nflicts) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e in MeetingsView
…port + chat buttons)
- Took main's versions of AppSettings, MailModels, AppSettingsStore, CalendarService, GoogleAuthService, MailService, MeetingNoteService, MailFeatureTests (mail intelligence feature set wins) - ContentView: merged handleRecordingChange() — kept dev's blockId callback logic inside main's extracted helper method - project.pbxproj: kept both sides' file refs (GatewayView, MentionPickerView from dev; KeychainSecretStore, MailIntelligence* from main), kept WebKit.framework (used by MailPaneView), dropped ThreadPickerRow ref (file does not exist), added MARKETING_VERSION + .dev bundle ID from main Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…summary - Switch transcription to FluidAudio (Whisper) with 5s chunked recording via AVAudioEngine + AsrManager; keep SFSpeechRecognizer as #else fallback - Add floating recording pill (always-on-top NSPanel) with animated bars, duration counter, stop button, and tap-to-navigate - Transcript drawer with right-aligned chat bubbles, search, copy-with-checkmark feedback, and scroll-to-bottom on open - AI summary via claude CLI: cleanTranscript + extractStructuredSections, result injected as editable Block children via MarkdownBlockParser.parse - afterStateView: editable title (axis: .vertical), ladybug Generate button, generate guard/disable, summary content in lighter gray vs user notes - Sidebar chat icon updated to bubble.left.and.bubble.right - Simplify pass: extract rmsLevel helper, incremental transcript join (O(1) append vs O(N2) rejoin), timer cleanup on chunk error, parseSections computed once per render, transcriptBottomAnchorID constant, markdownToBlocks uses MarkdownBlockParser Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1adaa37ff5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <key>NSMicrophoneUsageDescription</key> | ||
| <string>Bugbook needs microphone access to record meeting audio for live transcription.</string> | ||
| <key>NSSpeechRecognitionUsageDescription</key> | ||
| <string>Bugbook uses speech recognition to transcribe meeting recordings in real-time.</string> | ||
| <key>SUFeedURL</key> |
There was a problem hiding this comment.
Restore speech usage description for fallback recognizer
This commit removes NSSpeechRecognitionUsageDescription, but the new fallback path still calls SFSpeechRecognizer.requestAuthorization when FluidAudio is unavailable (TranscriptionService.startRecording under #else). On macOS, requesting Speech permission without that Info.plist key causes the app to fail at runtime, so builds/environments that rely on the fallback recognizer will not be able to start recording.
Useful? React with 👍 / 👎.
| // Find the @<filter> token nearest to the anchor and replace it. | ||
| if let range = block.text.range(of: searchToken) { | ||
| block.text.replaceSubrange(range, with: mention) |
There was a problem hiding this comment.
Replace mention at anchor instead of first token match
insertMention currently replaces block.text.range(of: searchToken), which always targets the first matching @... token in the block. If the same mention prefix appears earlier in the text, selecting a mention from the picker edits the wrong occurrence and leaves the one at the cursor unchanged. The picker already tracks mentionPickerAnchorPos, so this replacement should be anchored to that position.
Useful? React with 👍 / 👎.
Summary
AVAudioEngine+AsrManager;SFSpeechRecognizerkept as#elsefallback. Model pre-warmed at startup so first recording starts immediately.NSPanelwith animated blue bars, live duration counter, stop button, and tap-to-navigate.#B1D4F9), sentence-level splitting, search with auto-focus, copy button with checkmark feedback, scroll-to-bottom on open.claude --model haikuvia shell process;cleanTranscript+extractStructuredSections; results injected as editableBlockchildren viaMarkdownBlockParser.parse. Ladybug Generate button with spinner + disable guard.rmsLevelhelper (dedup), O(1) transcript append (was O(N²) rejoin), chunk timer cleanup on error,parseSectionscomputed once per render,transcriptBottomAnchorIDconstant,markdownToBlocksreplaced byMarkdownBlockParser.parse.Test plan
🤖 Generated with Claude Code