Repository navigation
Releases: Rawgeek/call-recorder
Release list
Call Recorder 0.1.40
Added
- The microphone menu updates when an input connects, disconnects, or becomes the system default.
- Settings offers a twenty-second microphone check through the same capture path used for recordings.
- The recording view warns when microphone permission is missing and offers permission repair controls.
- Review Speakers offers to download the pinned speaker models when they are missing from the local cache.
Fixed
- The speech runtime installer restores pip when the Python environment was created without it.
- Recording startup reserves capture before waiting for microphone setup, preventing overlapping starts.
- Stopping a microphone check waits for pending startup and cleanup before recording can use the input.
- Permission resets and Restart cannot interrupt a recording, capture startup, or a microphone check.
Runtime 84028d19
Supporting runtime for Call Recorder 0.1.40.
This is not the app download. Call Recorder fetches this archive for transcript search and its MCP server.
SHA-256: 84028d19001b3edd6341d6583a92ca4ee7c50bea9471b10ed79a623fc12900f2.
Call Recorder 0.1.19
The model that is already on disk keeps being used after the catalog renames it, so briefs keep
working across the 0.1.18 model change.
Fixed
- An installed model is read under the name it was downloaded with. 0.1.18 moved the brief to
Qwen3.5, which renamed both the repository and the file. The installed copy was looked for under
the catalog's new names and found nowhere: the brief model was reported as not downloaded while
2.5 GB of it sat on the disk, and the pane offered to download the same weights again under a
name they never had. The installed record is what describes the copy on disk, so its repository,
revision, and file names are what the app reads. The copy already there is used until the update
is taken, and the pane's own "A newer copy is published" row is where taking it is offered.
Call Recorder 0.1.18
A name that was confirmed stays confirmed, and the brief of a long call is written by a newer model
and finishes the sections it starts.
Fixed
- A confirmed voice no longer comes back to review at every launch. The repair that takes a
person's name off a fragment that does not sound like them compared the fragments with each other,
so a voice the diarizer split across two fragments was handed back at the start after every
confirmation, and the hand-back deleted the voiceprint that confirmation had just stored. A
voiceprint does not move when the same comparison is run again, so no answer could end the loop:
the same voice was confirmed, returned, and confirmed again over two days. The repair now asks the
question its own message states -- whether the fragment sounds like the person at all -- and it
hands a fragment back once. The answer given after that stands until someone hands the fragment
back by hand. - A call with many people on it is no longer cut off. The brief of a long call is asked for
under 150 words and was capped at 512 tokens, which a fifteen-person call reached: the saved brief
stopped inside its last section, and one came back with a section heading and nothing under it.
Every run measured at the new cap of 700 tokens finished on its own.
Changed
- The brief is written by Qwen3.5 4B, quantised the same way the model before it was (4-bit
Q4_K_M, 2.7 GB, Apache-2.0). On the call this was measured with, it read the transcript in 17
seconds where the previous model took 30 and wrote its answer in 10 where that one took 13; its
tokenizer spends about 15% fewer tokens on the same Russian, which is context and time both. The
model reasons before it answers unless its template is told not to, so the request asks it not to,
and a reasoning block that arrives anyway is removed before the brief is saved. - The prompt names the language of the call after the transcript, not only in the rules above
it. Handed a long Russian call and a sheet of English instructions, the new model answered in
English: a translation nobody asked for, and the failure the language rule exists to prevent.
Named in words, as the last thing read, it answered in Russian in every measured run. - A supporting model's row says which copy is installed. The model's own version -- the size and
the quantisation, which is what decides how much memory the run needs -- was written in the
catalog and shown nowhere, so one download could not be read apart from another.
Call Recorder 0.1.17
The Models pane stops saying the host does not publish a file it does publish, and the runtime the
app fetches is published with the release.
Fixed
- The JavaScript runtime is published with the release. The app does not carry the runtime: the
bundle records the archive's hash and fetches it from a release of its own, named for those bytes.
0.1.16 was published without that release, so the runtime download answered with a page that was
not the archive, the Models pane said the download did not match the hash recorded when the app
was built, and Retry asked for the same missing address. The archive is published now, and
publishing it is part of the release: it is created when it is not there, and a release is not
called verified until the runtime it fetches is published with the hash the bundle records.
Changed
- A small file is checked by the name the host publishes for it. A host hashes what it publishes
one of two ways: a large file carries a SHA-256, and a small file carries only the name it has in
the host's repository, which is a hash of the contents too. The update check understood the first
and ignored the second, so the embedding model, whose files include a config.json and a tokenizer
configuration, was reported as one the host had stopped publishing, with no verdict possible for
as long as it was installed. The app computes the same name for the copy on disk and compares
them, which is a check of the contents rather than a size, and a copying update is verified the
same way when it arrives.
Call Recorder 0.1.16
Calls recorded before briefs existed can be written up now, without recording them again, and the
panel stops keeping the room of a notice that has gone away.
Added
- Write a brief, on the menu-bar row of any call that has a transcript and no brief yet. The
button appears when the runtime and the model are ready, and the row shows the work while it
runs. It is the same path the pipeline takes, so a brief written on request is the brief a call
would have been given had it finished after the update.
Changed
- A development run keeps its voice-profile key in a file instead of the keychain. Voice
profiles are sealed with a key that lives in a keychain item, and the keychain decides whether a
program may read one of its items by the program's signature: every rebuild is a new program to
it, so starting a build from the build directory waited on a password dialog with nothing on
screen to explain it. Those runs keep the key in a file only this account can read, inside the
app's own folder. The file holds the key the installed app keeps in the keychain, because both
programs read one library: the first development run that finds profiles already sealed copies it
out of the keychain, which is the one question it asks, and every run after that reads the file.
CALL_RECORDER_VOICEPRINT_KEY=keychainasks for the keychain throughout. The installed app keeps
using the keychain. - Packaging signs ad-hoc unless an identity is named, so building an app for this machine needs
no signing key and no password.scripts/release.sh --publishnames the release identity, so a
published build is still recognised by macOS across updates and keeps the permissions it was
granted.
Fixed
- The strip under the menu bar, when a notice went away. The panel is sized once, from the
tallest content it was shown, and it is drawn from the middle of the window it was given: the
notice that reported older calls it could not read left its room behind as a gap, and the panel
sat lower for as long as it stayed open. The panel now takes the height the content was measured
at every time that height changes, so the room goes back when the notice does. The measurement
has to come from the content: the panel's own content view reports a fitting size of zero, which
is what the first attempt at this fix relied on and why it changed nothing on screen.
Verified
- 648 tests pass in 83 suites. The request path shares the pipeline's transcript read, so it is
covered by the tests that already cover the brief. The panel was measured on the machine the
strip was reported on: with the notice it is 603 points tall, the notice goes, and it is 576 with
its top edge in the same place.
Call Recorder 0.1.15
A release about reading less. A call now comes with a brief: what it was about, what was agreed,
who owes what, and what was left open, in the language the call was held in, written on this Mac
by a model that runs on this Mac. The panel also stops sitting a strip below the menu bar, and
clicking the app's own menu no longer turns it into a bar.
Added
- Briefs. After a call is transcribed, a local model writes under a hundred and fifty words
about it: the ticket numbers, the decisions and who made them, the tasks and whose they are.
Settings -> General -> "Write a brief" turns it off; Settings -> Models downloads the model,
which is 2.4 GB and is used for nothing else. - The brief travels with the call. The menu-bar row marks a call that has one and copies it
when the brief button is pressed, and the MCP server returns it fromget_call, so a task that
needs the call's context reads a hundred and fifty words instead of the whole transcript. - llama.cpp is named where it is needed. The runtime that loads the brief model is found on
PATH, its version is shown in Settings -> Models, and the row says what to install when it is
missing:brew install llama.cpp.
Fixed
- The menu-bar panel sits against the menu bar on a display whose menu bar hides itself. Its
visible frame is the whole screen there, so the panel was placed against the top of the screen
and drew over the bar; the row the icon is drawn in is the measure that is right on both kinds
of display. - The panel is placed again as it appears. The system places its own window while it comes on
screen, which landed after the correction the app made, and left a strip between the bar and
the panel for as long as it was open. - Clicking the app's name in the menu bar no longer turns that menu into a bar. The fit walked
every borderless window of the app, and an open menu is drawn in one of those.
Verified
- 641 tests pass in 82 suites, twenty-five of them new: the words a brief is asked for in, the way
a transcript is read without its header, the cut a long call is made at, the brief table and its
replacement, the model host's own digests, the port the runtime is given, and the arithmetic the
panel is placed with on a display whose menu bar hides itself. - The brief was written by the real model on this Mac, through the same code the app runs: a
fifteen-minute invented call came back in 7.4 seconds with the ticket number, the names, and the
tasks in it, under two hundred words. The suite skips that test where the model is not installed. - The panel geometry is measured, not guessed. The running app's panel was found at 65 points
down a screen whose menu bar ends at 30, which is the strip: the numbers the fix is written
against are the numbers the window server reports.
Call Recorder 0.1.14
A release about how many people were speaking. The detector counts voices on its own, and on a long
standup it counted one too many: fourteen remote voices came back as sixteen, and two of those
voices had to be named by hand with a name the transcript already used.
Added
- Settings -> General -> Separate voices by the people on the call, on by default. The detector
answers exactly the number it is given, and the count is the people on the call less the person
recording. Measured on a real thirty-four minute standup: sixteen voices in a hundred and
forty-four seconds before, fourteen voices in eighty-six seconds after, with no hand naming. - Review Speakers counts the voices of a call and can separate them again. The number beside
the count is used for that call ahead of the list of people, so a call that came out wrong in
either direction - two voices where one person spoke, or one voice holding two people - is fixed
from the window that showed the problem.
Fixed
- The count is only asked for when the recording held room for that many voices to have spoken:
fifteen seconds each. A two-minute call with fourteen people named on it is left to the detector,
because a count that is too low writes two people into one voice, and that is the mistake that
costs a transcript.
Verified
- 616 tests pass in 78 suites. Nine are new: the count the app asks for on a standup, a small
call, a short call, a call with one other person, no local participant, the setting off, and the
floor measured against the number of voices rather than the length of the call - plus one that
the count reaches the speaker script under the name it knows. - The count was measured, not guessed. On the standup: sixteen voices in a hundred and forty-four
seconds with the detector deciding, fourteen in eighty-six with the count. On a three-person
call: four voices with two fragments with the detector deciding, exactly two with the count. - Loose bounds were tried and do nothing: asking for between ten and sixteen voices returned the
same sixteen as asking for nothing.
Call Recorder 0.1.13
A release about the two sides of a call. A recording that held one side said nothing about why, and
on a Mac with no audio input at all it could not be made. Both are answered here, together with the
speaker runtime that could not find the libraries it decodes with.
Added
- Settings -> General -> Record when there is no microphone, on by default. A Mac mini has no
audio input, and ScreenCaptureKit records the call's system audio on its own, so the other side is
captured and the transcript holds it. Turning the switch off keeps the older refusal, which is the
choice for a Mac that has a microphone and wants every recording to hold both sides. - The Screen Recording permission is read when the app starts, so the card that names it is on the
surface before a call rather than after one that failed. The card opens the pane that holds the
switch.
Fixed
- A start or a resume that macOS refuses for lack of Screen Recording now says so. It was reported
as a ScreenCaptureKit failure, and the sentence named no permission and no way to grant one. The
diagnostics still record the framework error, and a resume that fails this way leaves the call
paused, with the audio it holds, instead of ending it. - Speaker detection finds FFmpeg's shared libraries. TorchCodec loads them at runtime, and a GUI app
does not inherit the shell setup that makes them findable, so the check reported a runtime that
could not decode. The library directory of the FFmpeg the app selected is now passed to the child
process that does the speaker analysis, and nothing else in the app's environment changes. - The Speaker setup check decodes a real, one-second WAV through TorchCodec instead of loading the
model and stopping there. A runtime that cannot decode audio no longer reports itself ready. - Every capture refusal has a sentence a person can act on. Without one, a missing microphone
reached the surface as "The operation couldn't be completed". - The release signature carries the microphone entitlement.
Verified
- 607 tests pass in 77 suites. Eight are new: the two permissions, the absent microphone, the
FFmpeg library path, and the stored setting that records without one. - Said plainly: a recording made without a microphone holds the other side only, and no local
voice is in it. Diarization has one speaker to work with, and the person who recorded it is not
in the transcript. The switch is there to be turned off where that is not wanted.
Call Recorder 0.1.12
A correction to when the recorder starts by itself. It started for any app that took the
microphone, and two recordings in the recent list carry one side and no speech because of it. A
voice message, a dictation session, and a voice search all take the microphone and play nothing.
Fixed
- A recording that starts by itself now needs a two-way call. The app that holds the microphone
must also play audio, and it must do both for five seconds. A call lasts longer than that; a
voice message usually does not. The recorder's own capture never counts, and the ignore list for
the voice recorder, dictation, and the assistant still applies. - Every decision is written down, and the app that took the microphone is named in it:
starting by itself: <app> held the microphone and played the other side for 5 seconds, or
not starting: <app> holds the microphone and plays nothing. Read them in Console under the
subsystemlocal.callrecorder.app, categoryautomatic.
Verified
- 599 tests pass in 77 suites. Five of them are new: a microphone alone is not a call, a
microphone with the other side is, the recorder's own audio never qualifies, the holder is
named, and the window is longer than a voice message. - The rule was seen to fail before it was trusted. With the playing side ignored, "a process that
holds the microphone and plays nothing is not a call" fails. - Not covered, and said plainly: an app that holds the microphone and plays audio still
qualifies an automatic start. An assistant in a voice chat and a read-aloud are two of them. The
log line names the app, so the ignore list can grow from evidence instead of from a guess.