Build tl;dv

KINDAreplaces $18/mosaves $216/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A local recorder whose hard problems are capturing hours of audio without losing any of it, presenting a transcript that invents text as something the reader is expected to verify, and keeping a growing pile of recordings of other people under control.

estimated effort multi-daythe files for this build are in the project pack

CaptureRecord to short numbered segment files on disk, never one growing bufferTranscriptionA local speech model by default, a hosted one only if a key is presentSummaryOne model call over the transcript, every bullet carrying the line ids behind itLibrarySQLite index over a directory of meeting folders you can open in a file managerRetentionAudio deleted on a schedule, transcript and notes kept

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the recorder, the library and the workers.

    Get it nodejs.org, or your version manager. open ↗

    Verify node --version prints v22 or higher

  2. installfree

    Why Segment recording, clip cutting and format conversion all go through it, and the clip boundary work depends on its behaviour.

    Get it Your package manager, or the official builds. open ↗

    Verify ffmpeg -version prints a version and the build lists your audio input device

  3. installfree, plus disk for the model

    Why The default path keeps audio of other people on your machine, and the model size you choose decides both accuracy and how long a meeting takes to process.

    Get it Download a runtime and one model file, and note which model you used.

    Verify A two minute recording transcribes with timestamps in a time you are willing to wait

  4. have readyfree, or the price of a virtual device

    Why Recording the other side of a call is the part that differs most between operating systems and versions, and it decides whether this tool is useful or just records you.

    Get it Check the current documentation for your operating system version, then either use its supported capture interface or install a virtual audio device.

    Verify A test recording contains both your voice and audio played by another application

  5. decidefree

    Why The rule here is that you announce it, and deciding the wording once means you actually do it rather than deciding in the moment.

    Get it Write the sentence you will say and the retention period you will offer, and put both in the README.

    Verify The consent prompt in the application matches what the README promises

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- meetings(id, title, started_at, ended_at, folder, consent_note, state) · consent_note records who was told and how
- segments(id, meeting_id, ordinal, path, started_at, seconds, bytes) · the recording is a sequence of short files, not one buffer
- lines(id, meeting_id, start_ms, end_ms, text, no_speech_prob, avg_logprob, model_id, chunk_ordinal)
- markers(id, meeting_id, at_ms, label, created_at) · dropped live with a hotkey while the meeting runs
- clips(id, meeting_id, marker_id, start_ms, end_ms, path, created_at)
- summaries(id, meeting_id, model_id, prompt_version, created_at, bullets_json) · each bullet holds its text and the line ids it cites
- retention(meeting_id, audio_delete_after, audio_deleted_at) · the transcript survives the audio
- There is no column anywhere holding a summary sentence without a list of line ids beside it. A bullet that cannot cite is a bug.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
MEETINGS_DIRrequired~/MeetingsOne folder per meeting holding segments, transcript, notes and clips.
DATABASE_PATHrequired./data/meetings.dbThe index over the meeting folders. Rebuildable from them.
SEGMENT_SECONDSrequired60Segment length. This is how much a crash can cost you.
ASR_MODEL_PATHrequired./models/speech-medium.binThe local speech model. Its identifier is stored with every transcript line.
SUMMARY_API_KEYsecretoptionalsk-...redactedOptional hosted model for summaries. Without it the transcript and clips still work.
AUDIO_RETENTION_DAYSrequired30Audio is deleted after this. Transcripts, notes and clips survive.
CLIP_LEAD_SECONDSrequired30Lead-in and lead-out either side of a marker when cutting a clip.

The build, in order

  1. Capture that survives a three hour call

    Recording writes continuously to disk in short segments and a mid-meeting failure costs seconds, not hours.

    1. The meeting is the folder; the file is only the last few seconds at risk.

      Files src/capture/recorder.tstests/segment-crash.test.ts

    2. Capturing another application's audio is an operating system question with a different answer on each one, so check the current documentation for your version before designing around it.

      Files docs/audio-capture.md

    3. Afterwards it is a form nobody fills in.

      Files src/capture/start.ts

    done when · tick each as it passes
    watch out
    • Recording into one file that is only finalised on stop means a crash, a full disk or an unplugged interface leaves a file with no usable header and the whole meeting is gone, which is exactly when you most needed it. Write short segments, close each one properly, and treat the meeting as the folder rather than the file.
  2. A transcript the reader can check

    Every transcript line carries its timestamps and its confidence signals, and the audio behind it plays on a click.

    1. A boundary in the middle of a sentence is where transcripts go wrong.

      Files src/transcribe/chunks.tstests/overlap.test.ts

    2. Silence is where invented sentences come from.

      Files src/transcribe/vad.ts

    3. The reader deciding whether to trust a line needs the number.

      Files src/transcribe/store.ts

    done when · tick each as it passes
    watch out
    • Feeding a long silence or a stretch of hold music to a speech model produces confident, grammatical sentences that nobody said, and they look identical to real transcript lines in a text file. Cut non-speech spans before transcription, keep the no-speech probability on every line, and mark low-confidence lines in the interface rather than hiding the number.
  3. A summary that cites or says nothing

    Notes and action items are generated only with the transcript lines they came from attached.

    1. A claim without a source is not a note, it is a guess.

      Files src/summary/prompt.ts

    2. The model will cite lines that do not exist.

      Files src/summary/verify.tstests/citations.test.ts

    3. So a strange bullet can be traced rather than argued about.

      Files src/summary/store.ts

    done when · tick each as it passes
    watch out
    • A clean five bullet summary with no links is the most dangerous artefact this application can produce, because it is exactly the thing people forward, and neither the sender nor the receiver can tell which sentence came from a hallucinated transcript line. Require citations, verify them mechanically, and drop the bullets that fail rather than showing them unmarked.
  4. Markers while it happens, clips afterwards

    A hotkey during the meeting marks a moment, and each marker becomes a clip you can play or hand over.

    1. The moment worth clipping happens while you are looking at the call.

      Files src/capture/hotkey.ts

    2. Segment start and duration are the only reliable clock here.

      Files src/clips/cut.tstests/clip-boundary.test.ts

    3. A silent clip is a bug report you will never receive.

      Files src/clips/cut.ts

    done when · tick each as it passes
    watch out
    • Cutting a clip by seeking into a single concatenated file falls apart the moment a segment is missing or a device changed sample rate mid-meeting, and you get silence or a clip from the wrong minute. Build the clip from the segment timeline, using each segment's recorded start and duration, and fail loudly if the requested range crosses a gap.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more meeting notes.