| name | noxrec |
| description | Operate and troubleshoot noxrec, the meeting recorder and transcriber. Use for "noxrec", "the recording failed", "I never got my transcript", "that meeting was not transcribed", "where is the transcript for", "re-run the transcription", "noxrec is stuck", "is it still recording?", or to follow a meeting while it happens. |
noxrec
Records a meeting as two separate tracks, microphone and system audio, transcribes them
through Mistral Voxtral and turns the result into a structured recap through Claude.
CONTRACT.md is the project's source of truth and describes every seam between components:
read it before touching anything structural.
Finding your way
Every command below is relative to the repository root, so locate it first. Ask the app,
which resolves it the same way it does for itself, applying the full precedence and the real
config grammar, and needs no repository to run:
/Applications/noxrec.app/Contents/MacOS/noxrec-menubar --print-config
Never read ~/.noxrec/config with grep or by eye to answer this, or anything else.
That file has a grammar the project defines and implements in three languages, kept
identical by a conformance test: surrounding spaces, optional quotes, a # that starts a
comment only at the beginning of a line, and the last occurrence of a key winning over
earlier ones. Any ad-hoc reading is a fourth parser that disagrees with the three real ones,
and it will disagree exactly on the edge case that matters. Once inside the repository,
bin/noxrec config prints the same settings, but not the same view of this one key: the
glue never reads what the app recorded inside itself, so it shows nothing when that is the
only source. For the repository path, trust the app. If nothing answers, ask. Do not guess.
Everything that describes the machine lives in ~/.noxrec/config, outside the repository.
Never guess a path, ask for it:
bin/noxrec config
bin/noxrec status
A session is a <NOXREC_MEETINGS_DIR>/YYYY-MM-DD_HHMM/ folder holding mic.wav and
system.wav, then transcript.txt and recap.md once the meeting is over.
Three rules you must not break
A session is finished if and only if transcript.txt exists. External automations fire
as soon as transcript.txt and recap.md both exist. Writing either by hand during a
meeting would send them off on an unfinished one, and a folder they already processed is
never replayed.
Never write inside a session folder. It belongs to noxrec. The live.* files are
disposable drafts; transcript.txt is the deliverable.
The pipeline never deletes the WAV files. As long as they are there, nothing is lost: a
failed transcription can be replayed.
Starting a recording: only a human can
bin/noxrec start fails from a terminal, with "no display available for system capture".
This is not a malfunction: macOS binds the screen-recording grant to the responsible
process, which is the app when someone clicks its icon, and the terminal otherwise. If
status answers idle, say so and suggest clicking the menu bar icon. Do not run start
on their behalf.
A meeting produced no transcript
First, confirm nothing is still running. Replaying the pipeline writes transcript.txt,
which marks the session as finished for every external consumer, so doing it on a live
meeting fires those automations on a recording that is not over. It would also transcribe
WAV files still being written, whose RIFF header still reads zero.
bin/noxrec status
bin/noxrec live --status <session_dir>
pgrep -fl "noxrec-transcribe.mjs"
That third check matters as much as the other two: two pipelines running on the same folder
overwrite each other's output, and the later one wins whatever the order they finished in.
Then:
- Does the folder exist, and what is in it? Are the WAV files there, at a plausible
size? A 44-byte WAV is a bare header: the capture wrote nothing.
- Replay the pipeline on the folder, which redoes both the transcription and the recap:
node pipeline/noxrec-transcribe.mjs <session_dir>
It writes transcript.txt then recap.md, and never removes the WAV files.
- Read the whole error message. The pipeline names the offending configuration key when
one is missing, and tells a missing key apart from an unreadable file.
- The recap is best-effort: if it fails, the transcript is still produced and the
command exits successfully. A transcript without a recap is not a failed session.
Following a meeting while it happens
An optional daemon transcribes as the meeting unfolds, so its content can be read without
waiting for the end:
bin/noxrec status
bin/noxrec live <session_dir>
bin/noxrec live --status <session_dir>
bin/noxrec live --stop <session_dir>
Keep that path for the whole session. Never rediscover it by looking for "the most
recent meeting": on stop, noxrec deletes its state file before transcribing, so for several
minutes that search returns the wrong answer.
The daemon writes live.txt (readable), live.jsonl (canonical, authoritative) and
live-alerts.txt, which is what to watch to be woken up when something deserves attention.
It catches up from the start of the meeting, so starting it midway loses nothing, and it
stops on its own when the capture stops.
What the live view cannot know
On speakers, the two tracks leak into each other and the same sentence is captured twice.
Detecting the duplicate is reliable, deciding who spoke is not: measured on a real
corpus, the microphone copy comes first 46% of the time and the system copy 54%. The daemon
therefore merges those duplicates into a single utterance labelled with the configured
uncertain-speaker label, never guessing, and says so once. Do not attribute those utterances to anyone: a headset is
the actual fix.
Live, every guest carries the plain guest label with no number: windowing makes numbering
unstable, and false precision would attribute a commitment to the wrong person. The stable
distinction only appears in transcript.txt at the end.