Skip to content

v0.2.0: Settings overhaul, Debug tab, onboarding improvements, and bug fixes - #57

Merged
jatinkrmalik merged 26 commits into
mainfrom
ui/settings-debug-tab-and-scroll-fix
Mar 10, 2026
Merged

v0.2.0: Settings overhaul, Debug tab, onboarding improvements, and bug fixes#57
jatinkrmalik merged 26 commits into
mainfrom
ui/settings-debug-tab-and-scroll-fix

Conversation

@jatinkrmalik

@jatinkrmalik jatinkrmalik commented Mar 10, 2026

Copy link
Copy Markdown
Member

Summary

Comprehensive UI overhaul of Settings, onboarding wizard, and model loading pipeline ahead of the v0.2.0 release.


🆕 New: Debug Tab

Adds a dedicated Debug tab (🐞) to Settings, consolidating diagnostic tools:

  • Permissions — Microphone, Accessibility, Input Monitoring status with Re-check and Reset All Permissions buttons. Reset runs tccutil reset All com.vocamac.app with a confirmation dialog, then quits the app for a clean re-grant on next launch
  • Debug Logs — Log file name, entry count, Copy to Clipboard, Export to File…, and Clear (red) button with live count update
  • Application — Restart VocaMac and Quit buttons
  • ⚠️ Upgrade note explaining that permissions don't carry over after updates (CDHash limitation) and users must remove old entries before re-adding

Previously, Permissions lived in General and Debug Logs lived in About — both are now consolidated here.


🆕 New: Setup Wizard Access

Users can re-trigger the onboarding wizard from two places:

  • Menu bar popover → Setup Wizard (✨ wand icon, between Settings and Quit)
  • Settings → About → Show Setup Wizard… (blue link)

Both use NotificationCenter to communicate with the app-level OnboardingWindowManager.


🐛 Bug Fixes

Bug Root Cause Fix
Setup Wizard flashes and closes monitorOnboardingCompletion saw hasCompletedOnboarding = true and closed the window within 100ms Added force parameter that resets the flag when manually triggered
Onboarding never auto-launches No startup logic checked hasCompletedOnboarding to show the wizard Added delayed check in init() that opens onboarding if not completed
Model selection not persisted performStartup() always called loadModel() with no argument, auto-selecting Tiny regardless of saved preference Now loads user's preferred model from selectedModelSize if downloaded
Documents folder permission prompt WhisperService created WhisperKitConfig() without downloadBase, defaulting to ~/Documents/huggingface Set downloadBase to ~/Library/Application Support/VocaMac/models
Onboarding button rendering glitch macOS default button chrome overlapped custom styling on Open Settings, Use This Model, Download Added .buttonStyle(.plain) to all custom-styled buttons
Model recommendation mismatch Onboarding used SystemInfo.recommendModel() (RAM heuristic → Medium) while Models tab used WhisperKit (→ Large v3) Onboarding now uses appState.deviceRecommendedModel
Completion step cut off Fixed window height couldn't accommodate all step content Wrapped step content in ScrollView, reduced window to 580px
Clear button not red role: .destructive doesn't render red in grouped Form Used explicit .foregroundStyle(.red)
Log count not updating after clear Static computed property had no state binding Tracked as @State for immediate view refresh

🎨 UI Improvements

  • Scrollbar consistency — Removed .padding(.horizontal) from General and Audio tabs so scrollbar sits flush at window edge, matching Models tab
  • Models tab — Moved WhisperKit recommendation and Model storage info below the info text
  • Model loading phases — Added loadingStatus to WhisperModelInfo with descriptive phases (Preparing… → Unpacking model… → Configuring… → Loading model… → Compiling neural engine…) shown in both onboarding and Settings
  • Onboarding permissions — Yellow ⚠️ warning when permissions are missing; Continue always enabled
  • Onboarding navigation buttons — Custom-styled Back (gray) and Continue/Start (blue) buttons replacing default macOS button chrome
  • Onboarding scroll — All step content wrapped in ScrollView so navigation buttons are never clipped
  • About tab — Cleaned up: removed Debug Logs (→ Debug tab), added Setup Wizard link
  • Debug LogsLabeledContent rows for Log File and Log Entries, full button labels, macOS-native share icon

📝 Documentation

  • README: Troubleshooting — Reset onboarding (defaults delete), reset preferences, reset permissions (tccutil) on update
  • README: Permission reset — Why Accessibility/Input Monitoring reset on rebuild (CDHash-based TCC tracking), why Microphone doesn't, workaround table
  • README — Updated tab count (4 → 5) in architecture diagram and project structure
  • RELEASE.md — Version checklist now includes SettingsView.swift and web/index.html
  • .gitignore — Added *.dmg and dmg-staging*/

Files Changed (22 commits)

File Changes
Sources/VocaMac/Views/SettingsView.swift Debug tab, About cleanup, scrollbar fix, clear logs, reset permissions, upgrade note
Sources/VocaMac/Views/OnboardingView.swift Button fixes, recommendation fix, permission warning, loading indicator, ScrollView, nav button styling
Sources/VocaMac/Views/MenuBarView.swift Setup Wizard button
Sources/VocaMac/App/VocaMacApp.swift Force-reopen onboarding, notification listener, auto-launch, @mainactor, window height
Sources/VocaMac/Models/WhisperModel.swift loadingStatus property
Sources/VocaMac/Models/AppState.swift Loading phase callbacks, preferred model on startup
Sources/VocaMac/Services/WhisperService.swift onPhaseChange callback, downloadBase fix
Sources/VocaMac/Services/Logger.swift logEntryCount, clearLogs()
README.md Troubleshooting, permission docs, tab count
.gitignore DMG artifacts

- Move Permissions section from General tab to new Debug tab
- Move Debug Logs (Copy/Export) from About tab to Debug tab
- Remove .padding(.horizontal) from General and Audio tabs so
  scrollbar position is consistent across all tabs
- New Debug tab uses Form with .formStyle(.grouped) matching
  the General and Audio tabs for visual consistency

Closes: scrollbar position mismatch between tabs
@jatinkrmalik
jatinkrmalik force-pushed the ui/settings-debug-tab-and-scroll-fix branch from 726d007 to 7eb8e2d Compare March 10, 2026 18:34
…s tab

Debug tab:
- Add Log File name and Log Entry count as LabeledContent rows
- Use full button labels (Copy to Clipboard, Export to File…)
- Use share icon (square.and.arrow.up) for export, matching macOS conventions
- Space buttons with Spacer for balanced layout

Models tab:
- Move WhisperKit recommendation and Model storage lines from
  System Information section to below the info text at the bottom
- Keeps System Information focused on hardware specs only

Logger:
- Add logEntryCount computed property for Debug tab display
- Add button in About tab to re-trigger the onboarding wizard
- Uses NotificationCenter to communicate between Settings and
  the app-level OnboardingWindowManager
- Styled as a plain blue link with wand.and.stars icon to match
  the About tab's clean aesthetic
Add *.dmg and dmg-staging*/ patterns to prevent build
artifacts from showing up in git status.
Add 'Setup Wizard' option between Settings and Quit in the
menu bar actions section. Uses the same NotificationCenter
mechanism as the About tab button to trigger onboarding.
Add 'Application' section in the Debug tab with:
- Restart VocaMac — relaunches the app (useful after permission changes)
- Quit VocaMac — terminates the app (destructive style)
- Helper text explaining when restart is useful
The onboarding completion monitor was checking hasCompletedOnboarding
every 100ms and closing the window immediately because the flag was
already true from the initial onboarding.

Fix: add force parameter to OnboardingWindowManager.open() that
resets hasCompletedOnboarding before showing the window. The manual
trigger (Settings About tab + Menu Bar) passes force: true, while
the first-launch flow uses the default force: false.
@jatinkrmalik
jatinkrmalik force-pushed the ui/settings-debug-tab-and-scroll-fix branch from edd8e76 to 27231b5 Compare March 10, 2026 18:51
Button glitch:
- Add .buttonStyle(.plain) to Open Settings, Use This Model, and
  Download buttons in onboarding to prevent macOS default button
  chrome from conflicting with custom styling

Recommendation inconsistency:
- Onboarding was using SystemInfo.recommendModel() (simple RAM heuristic)
  which recommended Medium for 48GB M4 Pro
- Models tab was using WhisperKit.recommendedModels() which recommended
  Large v3 for the same device
- Fix: onboarding now uses appState.deviceRecommendedModel (WhisperKit's
  recommendation) matching the Models tab exactly
…vior

Onboarding:
- Allow Continue even when permissions are not all granted
- Show yellow warning banner when permissions are missing:
  'Some permissions are missing. VocaMac may not work correctly
  until all permissions are granted.'
- Direct users to Settings → Debug for later setup

README:
- Add detailed explanation of why permissions reset on rebuild
  (CDHash-based TCC tracking, not bundle ID)
- Explain why Microphone persists but Accessibility doesn't
- Add workaround table: re-grant, Terminal trick, Developer ID
- Developer tip for Terminal-based permission inheritance
@jatinkrmalik jatinkrmalik changed the title ui: add Debug tab and fix settings scrollbar consistency ui: Settings overhaul — Debug tab, Setup Wizard access, and onboarding fixes Mar 10, 2026
WhisperService was creating WhisperKitConfig() without setting
downloadBase, causing WhisperKit to default to ~/Documents/huggingface
for model storage. This triggered a macOS Documents folder access
permission dialog on first launch.

Fix: set downloadBase to ~/Library/Application Support/VocaMac/models,
matching ModelManager's existing download path. Models are stored in
Application Support where no user-facing permission prompt is needed.
Increase onboarding window height from 550 to 620 to prevent
the Back/Start Using VocaMac buttons from being clipped on the
final completion step.
Show a spinner with 'Loading model…' text in the ModelSelectionCard
when a model is being loaded, using the existing isLoading property
from WhisperModelInfo. Previously the button just disappeared with
no feedback, making it feel stuck.
Add loadingStatus property to WhisperModelInfo that shows the
current phase of model loading:
- Preparing… → Unpacking model… → Configuring… → Loading model… → Compiling neural engine…

WhisperService.loadModel() now accepts an onPhaseChange callback
that AppState uses to update the loading status in real-time.

Both the onboarding ModelSelectionCard and Settings ModelRow
now display the descriptive status instead of a generic 'Loading…'
Add yellow warning in the Permissions section explaining that
after updating VocaMac, users must remove the old entry from
Accessibility and Input Monitoring and re-add the new version,
since permissions don't carry over with ad-hoc signing.
Add clearLogs() method to VocaLogger that truncates the log file.
Add a red destructive Clear button (trash icon) in the Debug Logs
section alongside Copy and Export.
- Use explicit .foregroundStyle(.red) on Clear label instead of
  role: .destructive which doesn't render red in grouped Form
- Track logEntryCount as @State so clearing logs triggers a
  view refresh and updates the count immediately
@jatinkrmalik jatinkrmalik changed the title ui: Settings overhaul — Debug tab, Setup Wizard access, and onboarding fixes v0.2.0: Settings overhaul, Debug tab, Setup Wizard, and onboarding improvements Mar 10, 2026
There was no startup logic to check hasCompletedOnboarding and
show the onboarding wizard. Added a delayed check in init() that
opens the onboarding window 0.5s after launch if the user hasn't
completed it yet.
performStartup() always called loadModel() with no argument,
causing WhisperKit to auto-select Tiny regardless of the user's
saved preference in selectedModelSize.

Fix: check if the user has a preferred model that's already
downloaded and load that instead. Falls back to auto-select
only on first launch when no preference exists.
Replace default macOS button chrome on Back, Continue, Finish,
and Start Using VocaMac buttons with custom-styled buttons
matching the rest of the onboarding UI:
- Back: gray background, rounded corners
- Continue/Finish/Start: blue background, white text, rounded corners
- All use .buttonStyle(.plain) to prevent default button chrome
Add a red 'Reset All Permissions' button that runs tccutil to
clear all TCC permission grants for VocaMac. Shows a confirmation
alert explaining the action, then quits the app so permissions
take effect on next launch.

Useful when permissions appear stuck or aren't recognized after
an update due to CDHash changes from ad-hoc signing.
Add guidance in Troubleshooting section recommending users reset
permissions via Settings → Debug → Reset All Permissions (or
tccutil) when updating to a newer version. Also add reset as the
top entry in the workarounds table.
620px still clips the Back/Start Using VocaMac buttons on the
completion step with custom-styled buttons.
Wrap step content in ScrollView so all steps handle overflow
gracefully instead of clipping navigation buttons. Reduce window
height from 680 to 580 since scrolling now handles varying
content sizes.
@jatinkrmalik jatinkrmalik changed the title v0.2.0: Settings overhaul, Debug tab, Setup Wizard, and onboarding improvements v0.2.0: Settings overhaul, Debug tab, onboarding improvements, and bug fixes Mar 10, 2026
Test expected 'Loading...' (three dots) but loadingStatus default
uses 'Loading…' (Unicode ellipsis) for typographic consistency.
Model switching from onboarding wasn't persisting correctly.
Remove the step for now — users can change models via Settings →
Models tab which works reliably. Reduces onboarding from 6 to 5
steps. Step numbering now uses dynamic count.
Remove modelSelection references and update step count from 6 to 5.
Use dynamic count in step number assertion.
@jatinkrmalik
jatinkrmalik merged commit af9e4d5 into main Mar 10, 2026
1 check passed
@jatinkrmalik
jatinkrmalik deleted the ui/settings-debug-tab-and-scroll-fix branch August 22, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant