19 Commit-ok

Szerző SHA1 Üzenet Dátum
hariel1985
78caac8d04 Fix silent live preview on stereo and multi-input audio interfaces
AVAudioConverter keeps only channel 1 when downmixing stereo and outputs
pure silence for layout-less multi-channel inputs (e.g. a 4-input USB
interface such as the UA Volt 476P), so the dictation model heard nothing
and the HUD never showed text. Pick the channel that carries the voice
(loudest on smoothed energy, switching only on a clear 6 dB margin) and
convert it as mono. Also reserve the dictation locale, which the Speech
framework warns will become required, and log the mic format.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 12:25:58 +02:00
hariel1985
fef0cd4ade Update README for 1.4.0
Also correct the requirement to macOS 26: the app is built against the
macOS 26 SDK with a macOS 26 deployment target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:29:30 +02:00
hariel1985
3890cd8ab4 Bump version to 1.4.0
Minor release: live transcript preview in the recording HUD using the
on-device Apple dictation model, with Whisper still producing the final
pasted text.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:29:30 +02:00
hariel1985
0983ba0fde Add live transcript preview in the recording HUD
While recording, the HUD now shows a rough live transcript using macOS's
on-device dictation model (SpeechAnalyzer + DictationTranscriber), which
also supports Hungarian. It is only a preview: Whisper still produces the
pasted text.

The preview captures the microphone with its own AVAudioEngine, leaving
the AVAudioRecorder path for Whisper untouched, so a preview failure just
means no preview. Audio is buffered from the moment recording starts so
the first words aren't lost while the model spins up; dictionary terms
are passed as contextual strings and replacements are applied to the
preview text. The dictation model for the selected language is
registered/downloaded at launch and on language change, and awaited
inline if needed.

The HUD is wider and shows the last three lines of the transcript; after
recording it stays up as "Transcribing…" until the final text is pasted.
A "Live preview while recording" setting (on by default) turns it off.
No extra permission is required beyond the microphone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:29:30 +02:00
hariel1985
b8f4a222f8 Update README for 1.3.1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:00:27 +02:00
hariel1985
71178c81bd Bump version to 1.3.1
Patch release: quantized Whisper models (Turbo q5_0 needs ~0.7 GB RAM
instead of ~1.75 GB), a download progress window, and model warm-up at
recording start with a HUD notice when the first transcription is slow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:00:02 +02:00
hariel1985
4584d30e02 Add quantized models, download progress window and model warm-up
Quantized models: add Small q5_1, Medium q5_0, Large v3 Turbo q5_0/q8_0
and Large v3 q5_0 to the catalog. Turbo q5_0 keeps whisper-server at
~0.7 GB instead of ~1.75 GB with the same speed. Installed models show
their catalog name; the first-run wizard uses a popup instead of one
button per model.

Download feedback: a progress window with bar, size, speed, time left,
cancel and retry, followed by "loading" and "ready" steps. Progress also
shows in the menu bar icon, the status menu and the Settings button, and
the Settings model list refreshes when done. Only one download runs at a
time, an existing model is replaced only after a successful download, and
HTTP errors are reported instead of saving the error page as a model.

Model warm-up: start loading the model when recording starts instead of
after it stops. After 2+ minutes idle a tiny silent request pages the
model back in while the user talks; a dead server is restarted, and a
server that is still loading is awaited rather than loading the model a
second time via whisper-cli. If loading takes over 2.5 s the recording
HUD explains why this transcription is slower. Server start no longer
overwrites the recording/transcribing menu bar icon.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:00:02 +02:00
hariel1985
29d0c0e503 Update README for 1.3.0
Document the warm whisper-server, live mic-level HUD, and custom
dictionary; add them to the feature list and Settings; note the
loopback-only server and the one-time model load at startup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:02:20 +02:00
hariel1985
fdf8bf9743 Use English for all UI strings (HUD + dictionary)
The new HUD label and the dictionary table labels/placeholders were in
Hungarian; the rest of the app is English. Translated: "No audio input?",
"Recording…", "Dictionary (heard → replacement):", column titles
"Heard"/"Replacement", and the field placeholders/hint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:26:35 +02:00
hariel1985
aa241f55c8 Bump version to 1.3.0
Minor release: warm whisper-server backend (no per-dictation model
reload), live mic-level HUD with silence warning, and a custom
recognised->replacement dictionary that also biases the whisper prompt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:20:33 +02:00
hariel1985
913ce5ca1a Fix dictionary table: view-based editable cells, prune empty rows
The cell-based table couldn't be edited reliably (no click-to-edit, no
Tab between columns). Rewritten as a view-based NSTableView where each
cell is an editable NSTextField committed via controlTextDidEndEditing
(Enter/Tab/focus-loss). Tab now moves from "Felismert" to "Helyette".
Rows where both columns are blank are pruned on add and on window close,
so empty rows are never persisted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:12:33 +02:00
hariel1985
636a4acf97 Add custom dictionary (recognised -> replacement) with editable GUI
A single editable table in Settings ("Felismert" -> "Helyette"). Two
effects from one list:
- the replacement pairs are applied to every transcript (fix names/jargon,
  and "\n" expands to a real newline for spoken line-break commands);
- the "to" terms are fed to whisper as the initial --prompt to bias
  recognition toward the user's vocabulary.
Stored in UserDefaults; wired through both the warm server and the CLI
fallback. Settings window grown to fit the table + add/remove buttons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:04:15 +02:00
hariel1985
4c680f9e4d Add live mic-level HUD with silence warning
Shows a small floating, non-interactive panel while recording with a
segmented VU meter driven by AVAudioRecorder metering (averagePower).
If the input peak stays at silence for >1.2s it turns red and shows
"Nincs hangbemenet?" — surfacing the dead-mic case that previously
produced empty recordings and whisper hallucinations with no feedback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 08:59:33 +02:00
hariel1985
21be80ddb4 Add warm whisper-server backend (no per-dictation model reload)
Each dictation previously spawned whisper-cli with -m, reloading the full
1.5-1.6GB model (+ ~10s Metal init) every single time. This adds a
WhisperServer manager that keeps a whisper-server child process alive with
the model preloaded, so each utterance is a fast local HTTP POST to
/inference (~0.5s) instead of a multi-second cold start.

- Bundles whisper-server alongside whisper-cli (bundle-whisper.sh).
- Server (re)starts on launch and on model change; stops on terminate;
  picks a free loopback port; -nt (plain text) + -sns (fewer hallucinations).
- transcribe() prefers the warm server and falls back to a per-call
  whisper-cli spawn if the server is unavailable.
- Warm-up now starts BEFORE the blocking accessibility prompt so the model
  load overlaps with the user granting permissions.
- Info.plist: NSAllowsLocalNetworking for the loopback HTTP call.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 08:56:45 +02:00
hariel1985
865b194eeb Bump version to 1.2.1
Patch release shipping the hardened-runtime microphone fix
(device.audio-input + allow-jit entitlements). The previously released
1.2.0 build could not access the microphone once hardened-runtime signed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 06:36:21 +02:00
hariel1985
bd20988fa0 Add cs.allow-jit entitlement for whisper.cpp Metal backend
The bundled whisper-cli / ggml dylibs JIT-compile Metal shaders at
runtime; under the hardened runtime that needs com.apple.security.cs.allow-jit
or the process gets killed. Completes the entitlement set for the
notarized Developer ID build (alongside device.audio-input).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 13:41:51 +02:00
hariel1985
3e96a6e394 Fix microphone under hardened runtime: add audio-input entitlement
The v1.2.0 Developer ID re-sign enabled the hardened runtime but the
entitlements were missing com.apple.security.device.audio-input. Under
the hardened runtime tccd refuses to even prompt for the microphone and
denies kTCCServiceMicrophone outright, so the app recorded pure silence
and whisper hallucinated text on the empty audio. Adding the resource
-access entitlement restores the mic permission prompt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 13:34:05 +02:00
hariel1985
9cd0d3eaa5 Fix version: Info.plist CFBundleShortVersionString 1.0.0 → 1.2.0
The bundle's marketing version was stuck at 1.0.0 while the Makefile and the
shipped releases are 1.2.0. Align it so the app reports its real version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 21:57:03 +02:00
hariel1985
b0533f85f0 Add entitlements for Developer ID signing + notarization
WhisperDictate.entitlements: non-sandboxed hardened-runtime entitlements
(app-sandbox=false; cs.disable-library-validation for the bundled whisper-cli
+ ggml/whisper dylibs). Used to deep-sign the app with the company Developer ID
identity before notarization. Also ignore the stray Contents/CodeResources
signing artifact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 21:28:29 +02:00
7 fájl változott, egészen pontosan 1589 új sor hozzáadva és 190 régi sor törölve

1
.gitignore vendored
Fájl megtekintése

@@ -3,6 +3,7 @@ macos/build/
macos/WhisperDictate.app/Contents/MacOS/ macos/WhisperDictate.app/Contents/MacOS/
macos/WhisperDictate.app/Contents/Frameworks/ macos/WhisperDictate.app/Contents/Frameworks/
macos/WhisperDictate.app/Contents/_CodeSignature/ macos/WhisperDictate.app/Contents/_CodeSignature/
macos/WhisperDictate.app/Contents/CodeResources
WhisperDictate WhisperDictate
*.o *.o
*.dSYM/ *.dSYM/

Fájl megtekintése

@@ -12,21 +12,42 @@ A simple menu bar app for voice dictation using OpenAI Whisper (local, offline).
## macOS ## macOS
### What's new in 1.4.0
- 💬 **Live preview while recording** — the recording overlay shows what you're saying as you speak, using macOS's on-device dictation model (works in Hungarian too). It's a preview: the pasted text still comes from Whisper, so it can differ slightly. Toggle it in Settings.
### What's new in 1.3.1
- 🪶 **Quantized models** — *Large v3 Turbo q5_0* keeps the transcription server at ~0.7 GB RAM instead of ~1.75 GB, at the same speed (also Small q5_1, Medium q5_0, Turbo q8_0 and Large v3 q5_0)
- 📥 **Download progress window** — progress bar, size, speed, time remaining, Cancel/Retry; progress also shows in the menu bar and Settings
- 🔥 **Model warm-up at recording start** — if the model was paged out after a pause, it starts loading as soon as you start talking, not after you stop; the HUD tells you when a transcription is slower because the model is still loading
### What's new in 1.3.0
- ⚡ **Warm transcription server** — the Whisper model stays loaded in a background `whisper-server`, so each dictation is a fast local call (~0.5s) instead of reloading the 1.5–1.6 GB model on every utterance
- 📊 **Live mic-level HUD** while recording, which warns ("No audio input?") if the microphone stays silent
- 📖 **Custom dictionary** — an editable *Heard → Replacement* table that fixes names/jargon in the transcript and also biases recognition
### Features ### Features
- 🎤 Global hotkey (⌃⌥D) to start/stop recording - 🎤 Global hotkey (⌃⌥D) to start/stop recording
- ⚡ Fast transcription via a warm whisper-server (model stays loaded — no per-dictation reload), with automatic fallback to `whisper-cli`
- 📊 Live mic-level meter while recording, with a "no audio input" warning
- 💬 Live transcript preview in the recording overlay (on-device Apple dictation model; Whisper still produces the pasted text)
- 📖 Custom dictionary (heard → replacement) that also biases recognition
- 🔒 Fully offline - uses local Whisper model - 🔒 Fully offline - uses local Whisper model
- ⚡ Automatic paste into any focused app - ⌨️ Automatic paste into any focused app
- 📋 Clipboard preservation - your copied content is restored after paste - 📋 Clipboard preservation - your copied content is restored after paste
- ⚙️ Settings window with model selection dropdown - ⚙️ Settings window with model selection dropdown
- 📥 Built-in model downloader with progress indicator - 📥 Built-in model downloader with a progress window (speed, time remaining, cancel/retry)
- 🪶 Quantized model options for much lower memory use
- 🚀 Launch at login support - 🚀 Launch at login support
- 🔊 Sound feedback (optional) - 🔊 Sound feedback (optional)
- 📦 Self-contained - whisper-cli bundled in app - 📦 Self-contained - whisper-cli and whisper-server bundled in the app
### Requirements ### Requirements
- macOS 13.0+ - macOS 26 (Tahoe) or later
- Apple Silicon (M1/M2/M3) or Intel Mac - Apple Silicon (M1/M2/M3) or Intel Mac
### Quick Install (Download) ### Quick Install (Download)
@@ -74,8 +95,10 @@ make install
Click the menu bar icon → Settings to configure: Click the menu bar icon → Settings to configure:
- **Language**: Auto-detect or 31 supported languages - **Language**: Auto-detect or 31 supported languages
- **Model**: Select from installed models or download new ones - **Model**: Select from installed models or download new ones (✓ marks models already downloaded)
- **Dictionary**: Add *Heard → Replacement* pairs to fix names/jargon (use `\n` for a newline); the replacement terms also improve recognition
- **Sound feedback**: Toggle audio feedback on/off - **Sound feedback**: Toggle audio feedback on/off
- **Live preview while recording**: Show a rough live transcript in the recording overlay (on by default)
- **Launch at login**: Start automatically when you log in - **Launch at login**: Start automatically when you log in
### Whisper Models ### Whisper Models
@@ -91,8 +114,22 @@ Download models directly from the app or manually:
| Large v3 Turbo | 1.6 GB | ~4 sec | Best | **Recommended** - fast like Medium, accurate like Large | | Large v3 Turbo | 1.6 GB | ~4 sec | Best | **Recommended** - fast like Medium, accurate like Large |
| Large v3 | 3.1 GB | ~8 sec | Maximum | Difficult audio, max accuracy | | Large v3 | 3.1 GB | ~8 sec | Maximum | Difficult audio, max accuracy |
**Quantized variants** (q5/q8) have much smaller weights, so the model uses far less memory, with a small accuracy trade-off:
| Model | Size | Full-size equivalent |
|-------|------|----------------------|
| Small q5_1 | 181 MB | Small (466 MB) |
| Medium q5_0 | 514 MB | Medium (1.5 GB) |
| Large v3 Turbo q5_0 | 547 MB | Large v3 Turbo (1.6 GB) — measured ~0.7 GB RAM vs ~1.75 GB, same speed |
| Large v3 Turbo q8_0 | 833 MB | Large v3 Turbo (1.6 GB) — near-identical accuracy |
| Large v3 q5_0 | 1.0 GB | Large v3 (3.1 GB) |
Models are stored in `~/.whisper-models/` Models are stored in `~/.whisper-models/`
> With the warm server (1.3.0+), the selected model loads once at startup (a few seconds); after that each dictation skips the reload, so the speeds above are roughly the per-dictation transcription time.
>
> The server keeps the whole model in memory while it runs. If macOS pages it out after a long pause, 1.3.1+ starts loading it back as soon as you start recording, and the HUD shows *"Loading model into memory…"* if that takes a moment.
### Audio Feedback ### Audio Feedback
- 🔔 **Tink** - Recording started - 🔔 **Tink** - Recording started
@@ -114,6 +151,8 @@ Grant these in System Settings → Privacy & Security:
## Security ## Security
- All processing is done locally - no data leaves your device - All processing is done locally - no data leaves your device
- The live preview uses macOS's on-device dictation model (SpeechAnalyzer); it needs no extra permission beyond the microphone
- The bundled `whisper-server` is bound to `127.0.0.1` (loopback only) and is never exposed on the network
- Audio files are stored in private temp directory and deleted after transcription - Audio files are stored in private temp directory and deleted after transcription
- Clipboard is cleared after paste (transcript doesn't remain accessible) - Clipboard is cleared after paste (transcript doesn't remain accessible)
- Original clipboard content is preserved and restored after paste - Original clipboard content is preserved and restored after paste

Fájl megtekintése

@@ -2,7 +2,7 @@
APP_NAME = WhisperDictate APP_NAME = WhisperDictate
APP_BUNDLE = $(APP_NAME).app APP_BUNDLE = $(APP_NAME).app
VERSION = 1.2.0 VERSION = 1.4.0
# Directories # Directories
SRC_DIR = src SRC_DIR = src
@@ -11,7 +11,7 @@ BUNDLE_DIR = $(APP_BUNDLE)/Contents
# Compiler settings # Compiler settings
SWIFT = swiftc SWIFT = swiftc
SWIFT_FLAGS = -O -framework Cocoa -framework AVFoundation -framework Carbon -framework CoreGraphics -framework ServiceManagement SWIFT_FLAGS = -O -framework Cocoa -framework AVFoundation -framework Speech -framework Carbon -framework CoreGraphics -framework ServiceManagement
.PHONY: all clean build bundle install run dmg .PHONY: all clean build bundle install run dmg

Fájl megtekintése

@@ -2,35 +2,40 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleDisplayName</key>
<string>WhisperDictate</string> <string>WhisperDictate</string>
<key>CFBundleIconFile</key> <key>CFBundleExecutable</key>
<string>AppIcon</string> <string>WhisperDictate</string>
<key>CFBundleIdentifier</key> <key>CFBundleIconFile</key>
<string>com.whisperdictate.app</string> <string>AppIcon</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleIdentifier</key>
<string>6.0</string> <string>com.whisperdictate.app</string>
<key>CFBundleName</key> <key>CFBundleInfoDictionaryVersion</key>
<string>WhisperDictate</string> <string>6.0</string>
<key>CFBundleDisplayName</key> <key>CFBundleName</key>
<string>WhisperDictate</string> <string>WhisperDictate</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.0</string> <string>1.4.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>5</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>13.0</string> <string>13.0</string>
<key>LSUIElement</key> <key>LSUIElement</key>
<true/> <true/>
<key>NSHighResolutionCapable</key> <key>NSAppTransportSecurity</key>
<true/> <dict>
<key>NSMicrophoneUsageDescription</key> <key>NSAllowsLocalNetworking</key>
<string>WhisperDictate needs microphone access to record your voice for transcription.</string> <true/>
<key>NSAppleEventsUsageDescription</key> </dict>
<string>WhisperDictate needs accessibility access to paste transcribed text.</string> <key>NSAppleEventsUsageDescription</key>
<string>WhisperDictate needs accessibility access to paste transcribed text.</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSMicrophoneUsageDescription</key>
<string>WhisperDictate needs microphone access to record your voice for transcription.</string>
</dict> </dict>
</plist> </plist>

Fájl megtekintése

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Not sandboxed: WhisperDictate uses global Accessibility / synthetic
keystrokes and spawns a bundled CLI, which the App Sandbox forbids.
Distributed via Developer ID, not the Mac App Store. -->
<key>com.apple.security.app-sandbox</key>
<false/>
<!-- The app bundles whisper-cli + ggml/whisper dylibs in the app. Disabling
library validation lets the process tree load them without tripping the
hardened runtime's same-Team-ID check. -->
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<!-- Hardened-runtime resource-access entitlement. REQUIRED for microphone
access under the hardened runtime: without it tccd refuses to even
prompt and denies kTCCServiceMicrophone outright, so the app records
silence (and whisper hallucinates on the empty audio). Must be present
on any Developer ID / notarized build. -->
<key>com.apple.security.device.audio-input</key>
<true/>
<!-- whisper.cpp's Metal/ggml backend generates code at runtime; the
hardened runtime needs allow-jit so the bundled whisper-cli/dylibs
don't get killed for JIT. -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict>
</plist>

Fájl megtekintése

@@ -25,6 +25,17 @@ mkdir -p "$FRAMEWORKS_DIR"
cp "$WHISPER_CLI_REAL" "$MACOS_DIR/whisper-cli" cp "$WHISPER_CLI_REAL" "$MACOS_DIR/whisper-cli"
chmod +x "$MACOS_DIR/whisper-cli" chmod +x "$MACOS_DIR/whisper-cli"
# Copy whisper-server (warm, preloaded-model HTTP backend) from the same bin dir
WHISPER_BIN_DIR=$(dirname "$WHISPER_CLI_REAL")
WHISPER_SERVER_REAL="$WHISPER_BIN_DIR/whisper-server"
if [ -f "$WHISPER_SERVER_REAL" ]; then
cp "$WHISPER_SERVER_REAL" "$MACOS_DIR/whisper-server"
chmod +x "$MACOS_DIR/whisper-server"
echo "Copied: whisper-server"
else
echo "Warning: whisper-server not found at $WHISPER_SERVER_REAL"
fi
# List of dylibs to copy # List of dylibs to copy
DYLIBS=( DYLIBS=(
"libwhisper.1.dylib" "libwhisper.1.dylib"
@@ -49,9 +60,12 @@ for dylib in "${DYLIBS[@]}"; do
fi fi
done done
# Fix dylib paths in whisper-cli # Fix dylib paths in the bundled executables (whisper-cli + whisper-server)
for dylib in "${DYLIBS[@]}"; do for exe in whisper-cli whisper-server; do
install_name_tool -change "@rpath/$dylib" "@executable_path/../Frameworks/$dylib" "$MACOS_DIR/whisper-cli" 2>/dev/null || true [ -f "$MACOS_DIR/$exe" ] || continue
for dylib in "${DYLIBS[@]}"; do
install_name_tool -change "@rpath/$dylib" "@executable_path/../Frameworks/$dylib" "$MACOS_DIR/$exe" 2>/dev/null || true
done
done done
# Fix dylib paths in each dylib (they reference each other) # Fix dylib paths in each dylib (they reference each other)
@@ -67,8 +81,10 @@ for dylib in "${DYLIBS[@]}"; do
fi fi
done done
# Sign everything # Sign everything (ad-hoc; the release flow re-signs with Developer ID afterward)
codesign --force --sign - "$MACOS_DIR/whisper-cli" 2>/dev/null || true for exe in whisper-cli whisper-server; do
[ -f "$MACOS_DIR/$exe" ] && codesign --force --sign - "$MACOS_DIR/$exe" 2>/dev/null || true
done
for dylib in "${DYLIBS[@]}"; do for dylib in "${DYLIBS[@]}"; do
codesign --force --sign - "$FRAMEWORKS_DIR/$dylib" 2>/dev/null || true codesign --force --sign - "$FRAMEWORKS_DIR/$dylib" 2>/dev/null || true
done done

A különbségek nem kerülnek megjelenítésre, mivel a fájl túl nagy Load Diff