Skip to content

Releases: jej2k5/meetey

v2.0.0 — Recording you can rely on

Choose a tag to compare

@jej2k5 jej2k5 released this 06 Aug 21:11

The first version I'd trust with a meeting that matters.

1.4 and 1.5 lost recordings — repeatedly, in ways that were hard to see. This release fixes the cause and removes the conditions that let it hide.

What was wrong

The meeting watcher checked for windows every ten seconds, including while a recording was running. macOS treats a second look at the screen as a competing capture and terminates the live one, so recordings died a few seconds after starting.

It arrived as an improvement: keep reporting whether the watcher can see your screen, even mid-recording. It destroyed the thing it was reporting on.

The timeline was plain in the logs — a recording made before that check was introduced ran 34 minutes; every recording after it died in seconds.

Why it survived being fixed

Two reasons, both fixed here:

  • Updating didn't restart the watcher. macOS keeps running whatever it loaded at login, so the old code kept running and kept killing recordings while the update appeared to have worked.
  • The self-check passed while the bug happened in front of it. It reported "0.3 seconds written" of a six-second test as a tick, because it only asked whether any audio arrived. A capture that stops early is exactly the fault it exists to catch.

Nothing is lost any more

The audio file is valid at every moment while it's being written, not only once it finishes cleanly. Lose power, kill the process, close the laptop — whatever is on disk plays and transcribes up to that second.

Earlier versions wrote the file's header only at the end, so any interruption in an hour-long meeting destroyed all of it.

Transcripts arrive on their own

Within about a minute of a meeting ending, a readable timestamped transcript appears in ~/.meetey/recordings/. No Claude Code, no sign-in, nothing to remember — transcription runs locally.

Notes still need Claude, so they wait for you. /meetey writeup writes them for everything that piled up while you were away.

Also

  • Screen capture covers the whole app. Narrowing it to a single window cost four recordings — Google Meet replaces its window when you join a call, and a capture aimed at the old one dies, taking the audio with it. Close or mute anything sensitive before opting in.
  • A second meeting in the same window gets offered. Previously an instant Meet started after an earlier call was silently never suggested.
  • npx jej2k5/meetey verify proves the machine can record and transcribe, by doing both. Install and update run it and decline to claim success when it fails.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code. Grant Screen Recording permission if macOS asks — the binary is re-signed on every update, so it's treated as new.

If you had recordings that never produced notes, they're still there: /meetey writeup.

v1.5.2 — A closing window no longer ends the audio

Choose a tag to compare

@jej2k5 jej2k5 released this 05 Aug 18:50

A 32-minute meeting recorded six seconds. If you record with screen capture on, upgrade.

What happened

macOS captures audio and video through a single stream with a single scope. So narrowing screen capture to one window — the feature that keeps your other tabs and notification banners out of frame — narrowed the audio to that window's lifetime too.

Google Meet replaces its window when you join a call. The window chosen at the prompt stopped existing a few seconds later, and the entire recording stopped with it. Six seconds of audio, no screen content, and 32 minutes of nothing.

The fix

Audio and screen are now captured separately. Audio follows the app and cannot be ended by a window closing. Screen capture keeps its window narrowing, so nothing is lost on the privacy side.

A stopped capture is also acted on rather than quietly logged:

  • Screen capture stops — survivable. It says so and keeps recording audio.
  • Audio stops — the recording ends and saves what it has, instead of running on for half an hour writing nothing.

If a recording came out short

Nothing can be recovered from a recording that was already truncated; the audio was never written. Recordings made from here on are unaffected by this.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code, and grant Screen Recording permission if macOS asks — the binary is re-signed on every update, so it is treated as new.

v1.5.1 — The watcher's recordings actually work

Choose a tag to compare

@jej2k5 jej2k5 released this 05 Aug 16:01

If you use the watcher, upgrade. Three bugs, all of which failed silently, and one of which meant no recording the watcher made was ever transcribed.

Nothing the watcher recorded was transcribed

whisper-cli was called by name. That works from Claude Code, which inherits your shell's PATH, and never worked from the watcher — a background agent gets /usr/bin:/bin:/usr/sbin:/sbin and Homebrew installs elsewhere. Every attempt failed with ENOENT into a log file, so recordings simply appeared never to be written up.

Your existing recordings are fine. The audio was captured correctly; only transcription failed. Run /meetey stop in Claude Code, or ask it to transcribe the WAV in ~/.meetey/recordings/ directly.

A recording could hang and capture nothing

Asking macOS what's on screen doesn't reliably fail when Screen Recording permission is unresolved — it can simply never return. A capture would sit indefinitely: no audio, no file, no error, and nothing in the log to distinguish it from a recording that was working. One 35-minute meeting was lost this way.

That call is now bounded and says what a timeout means. The capture also reports each setup step, so a stall is visible rather than looking like success.

This is most likely to bite right after an upgrade: the binary is rebuilt and re-signed, macOS treats it as a new program, and a background agent can't put the permission prompt in front of you. Grant Screen Recording after upgrading.

Stopping the watcher killed a recording in progress

Stopping the watcher tears down everything it started, including a running capture — mid-write, with nothing saved and nothing queued. It now finishes the recording properly first.

An interrupted recording is also no longer lost: the audio is all there behind an unwritten header, and transcribing repairs it automatically.

Upgrade

npx jej2k5/meetey update
npx jej2k5/meetey watch enable

Re-running watch enable is worth it — it verifies the watcher can actually see your screen and tells you if permission is missing, rather than letting it fail quietly.

There is no bare meetey command; installing through npx puts nothing on your PATH.

v1.5.0 — You can see the watcher working

Choose a tag to compare

@jej2k5 jej2k5 released this 05 Aug 14:50

The watcher used to be invisible. Enabled or not, working or blind, there was no way to tell without running a command. Now it's in the menu bar for as long as it's on.

A presence, not a notification

watching     ◌   quiet dotted circle, sitting still
recording    ◉   red — this one steps aside for it

It's deliberately unlike the recording dot. Watching and recording are different things to be told, and a second attention-seeking icon would have weakened the only continuously-visible sign that a recording is happening. So while you're recording, the watcher's icon gets out of the way entirely and gives the red dot the bar.

It sits still. No pulse, no breathing, no heartbeat. It moves when something actually changes — settling in when the watcher starts, standing aside when a recording begins, coming back when it ends — and not otherwise. An icon that animates for hours in your peripheral vision is noise, not craft. macOS's Reduce Motion setting is respected.

Its menu tells you what it's doing, and stops the watcher if you want.

Turning it on tells you whether it worked

watch enable verifies it can actually see your windows before reporting success, which takes a moment. That moment now shows progress instead of appearing to hang.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code. If the watcher is already enabled, the icon appears the next time the watcher restarts — or run npx jej2k5/meetey watch enable to get it immediately.

There is no bare meetey command; installing through npx puts nothing on your PATH.

v1.4.2 — The watcher can tell you it's working

Choose a tag to compare

@jej2k5 jej2k5 released this 05 Aug 13:28

If you use the watcher, upgrade. It could previously run without seeing anything, and say nothing about it.

The watcher could be on and blind

macOS grants Screen Recording permission per process, so the watcher needs its own — separately from the one meetey-capture already has. Nothing asked for it, so most people wouldn't have granted it.

Turning the watcher on reported success regardless. It would then look for meetings, see nothing, write one line to a log nobody was pointed at, and repeat every ten seconds. No error, no prompt — just a watcher that never noticed a meeting, with no way to tell whether it was broken or you simply hadn't had one.

Enabling now checks before it congratulates itself, and if it can't see your windows it says so and names exactly what to switch on. Nothing is left installed that looks on but isn't.

The check runs from the agent itself rather than the installer, because permission is attributed to whichever process asks — a check run from the terminal would pass while the thing it just installed stayed blind.

Back-to-back meetings were missed

When a recording ended, the watcher transcribed it — and froze completely while doing so. On an hour of audio that's several minutes of being switched off, so a meeting starting right after one ended was missed entirely. Transcription now runs alongside the watcher rather than in front of it.

Status commands were quietly wrong

  • /meetey status said nothing was happening while a finished recording sat waiting to be written up — right after a notification told you to go collect it.
  • /meetey doctor, whose whole job is answering "is meetey working?", couldn't see the watcher at all. Now it reports whether the watcher is on and whether it can actually see anything.

Update checking

npx jej2k5/meetey status

now reports whether a newer version has been released.

This is the only part of Meetey that contacts a server. It's an anonymous request for the repository's latest release tag — nothing about you or your machine is sent. Cached for a day, two second timeout, skipped silently when offline. MEETEY_NO_UPDATE_CHECK=1 turns it off. /meetey doctor reports the same figure but never makes the request itself; it reads what the CLI last found.

Also

  • Enabling stopped claiming "audio only", which stopped being true when the prompt gained an audio + screen option.
  • A meeting you skipped stays skipped across a restart.
  • npx jej2k5/meetey watch log and ... watch logs both work.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code. If you had the watcher enabled, run npx jej2k5/meetey watch enable again — it will now tell you whether it can actually see your screen.

(There is no bare meetey command: installing through npx runs the package from its cache and puts nothing on your PATH. Earlier notes said otherwise — that was wrong.)

v1.4.1 — Recordings the watcher finished are no longer stranded

Choose a tag to compare

@jej2k5 jej2k5 released this 04 Aug 22:06

Fixes a bug in v1.4.0. If you used the watcher, upgrade.

The bug

Stopping a watch-agent recording from the menu bar left /meetey stop reporting "No active recording" — with the audio sitting on disk and no obvious way to reach it. The post-stop notification tells you to run /meetey stop, so it pointed straight at the dead end.

A recording started by the watcher ends in a different process from the MCP server. That process clears the "something is recording" state, which is correct, but nothing was left behind for /meetey stop to collect. Recordings started from /meetey start were unaffected.

The fix

Finished-but-uncollected recordings are now recorded on disk, so they survive the process that made them — and a Claude Code restart between stopping and writing up.

When there is genuinely nothing to collect, /meetey stop no longer dead-ends: it names the recordings that have audio but no notes, and offers to write the most recent one up.

Nothing was lost

Recordings affected by this are still in ~/.meetey/recordings/, and the watcher had already transcribed them. After upgrading, /meetey stop will point you at them.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code so the MCP server reconnects.

v1.4.0 — Recordings that start on offer and end by themselves

Choose a tag to compare

@jej2k5 jej2k5 released this 04 Aug 20:13

Meetey no longer needs you to think about it during a meeting. It can notice a call starting and ask, it shows what it is capturing while it runs, and it stops on its own when the call ends.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code so the MCP server reconnects. New installs: npx jej2k5/meetey install.

Changed behaviour

Existing recordings work differently after this upgrade, without you asking:

  • Recordings end themselves — when the app quits, when the captured window closes, or when the call itself ends. The last of those trims the file back to when the call ended, so the waiting never reaches your transcript.
  • A menu bar item appears while recording, showing what is being captured and for how long, with Stop Recording.

Both are on by default. autoStop: false, stopWhenCallEnds: false, and menuBar: false on start_recording turn them off individually.

Far fewer keyframe files

Screen capture used to write a JPEG whenever the picture differed from the last one. In the standard slide-plus-speaker-tile layout the moving tile always qualified, so a one-hour call filled its 200-frame budget in the first few minutes and recorded nothing after.

Two rules replace that:

  • A keyframe is written when the screen stops moving, not when it starts, so a slide transition collapses to the one settled frame — which also reads far better than anything caught mid-fade.
  • Regions that are always moving stop counting. A speaker tile, a progress bar, a clock.

Revisiting a slide you already showed no longer writes it twice; the manifest records that it came back.

Watch for meetings

npx jej2k5/meetey watch enable

Notices meetings in Chrome, Zoom, and Teams and asks before recording — naming the window, offering audio only or audio + screen. Off until you enable it, and it never starts a recording on its own. Also drivable from /meetey watch inside Claude Code.

Narrow what gets captured

Screen capture can now target a single window rather than everything an app displays, which keeps its other windows and notification banners out of frame. On a multi-monitor setup the display is chosen by where the meeting actually is, rather than whichever display came first.

macOS has no tab-level capture, so a window is as fine as it goes — to isolate one tab, drag it into its own window.

Also

  • Transcripts are produced as soon as a watched recording ends, so they are ready before you ask.
  • Ctrl+Shift+R / Ctrl+Shift+S are documented as what they are: shortcuts inside Claude Code, not system-wide hotkeys. Stopping from anywhere is what the menu bar is for.
  • sceneThreshold is reachable from start_recording; it was previously documented but not wired up.

Requires macOS 13+. After upgrading, macOS may ask for Screen Recording permission again — the capture binary is rebuilt and re-signed. Enabling the watcher asks separately for Node.

v1.2.0 — Admin tools for the meeting library

Choose a tag to compare

@jej2k5 jej2k5 released this 02 Aug 17:45

Your meeting archive is now answerable. Ask Claude Code about it instead of navigating it with ls and grep.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code so the MCP server reconnects with the new tools. New installs: npx jej2k5/meetey install.

Ask about your meetings

"what meetings do I have this week?"
"what did we decide about the API cutover?"
"show me the standup from Thursday"
"how much disk are my recordings using?"
"is meetey working? screen recording seems broken"
"delete the test recording from yesterday but keep the notes"

There is no separate app, dashboard, or web UI — the terminal you already work in is the admin surface.

What's new

Tool What it does
list_recordings The library — title, date, duration, transcript quality, keyframe count, size. Filter by date range, quality, or whether screen capture was on
get_recording One meeting in full, notes included, plus paths to its audio, transcript, and keyframes. By session ID or by date
search_recordings Search every meeting's notes and transcripts, returning the matching line with its [mm:ss] offset
delete_recording Removes a session's files. Shows what it would delete and frees nothing until you confirm; keepNotes drops the audio and keyframes but keeps the writing
system_status Install health, Screen Recording permission, active model, disk used — the first thing to check when something isn't working

Search is the one worth knowing about

Asking "what did we decide about the API cutover?" returns the decision, which meeting it was in, and the timestamp:

2026-08-01  [28:51]  (notes)       Move the API cutover to next sprint
2026-08-01  [28:51]  (transcript)  Lets move the API cutover to next sprint then.

You land on the second it was said, rather than opening a transcript and reading. This is what the timestamps introduced in v1.1.0 were for.

Scope it with scope: "notes" to search only decisions and action items, or scope: "transcripts" for everything that was actually said.

Deletion describes before it acts

delete_recording is a dry run unless you pass confirm: true. The first call returns the exact file list and frees nothing, so you always see what's going before anything goes. It also refuses to touch a session that's still recording.

keepNotes is the option you'll probably want: it reclaims the audio and keyframes — which are nearly all of the disk — while keeping the notes and transcript, which are small and are the part worth keeping.

Health in one place

system_status reports the capture binary and its code signature, whisper-cli, the model, MCP registration, the skill, hotkeys, Screen Recording permission, and the disk used by your library. Permission is the most common thing to go wrong and the hardest to diagnose from an error message, so it's checked directly rather than inferred.

Compatibility

No breaking changes. All six capture tools from v1.1.0 behave exactly as before; these five are additions.

Recordings made with earlier versions are picked up automatically, including notes from before v1.1.0 that used the old meetey-<epoch>.md filename. A transcript whose notes file has been deleted still appears in search rather than silently vanishing.

Requirements

macOS 13+, Node.js 18+, Xcode Command Line Tools, Claude Code, Homebrew.

Source-only release. The Swift capture binary is compiled and ad-hoc signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.

Licensed under the Apache License 2.0.

v1.1.0 — Screen capture and verifiable notes

Choose a tag to compare

@jej2k5 jej2k5 released this 01 Aug 19:00

Meetey now captures what was on screen, and its notes tell you where every claim came from.

Upgrade

npx jej2k5/meetey update

Then restart Claude Code so the MCP server reconnects. New installs: npx jej2k5/meetey install.

No new permissions. Screen capture uses the Screen Recording access you already granted for audio.

Screen capture — opt-in, per meeting

Meetey can capture slides, screen shares, code, and diagrams alongside the audio, and fold them into the notes.

/meetey start --video       Audio + screen keyframes
/meetey start --audio-only  Audio only

It is off by default and asked for every time. There is no setting that turns it on permanently — that's deliberate, because screen capture records everything the target app displays, including other tabs, other windows, and notification banners.

It doesn't record video. It samples once a second and keeps a frame only when the picture materially changes, so an hour-long meeting produces a few dozen keyframes rather than 3,600:

Storage/hr Sent to Claude
Audio ~115 MB ~12K tokens (transcript)
Screen keyframes ~10 MB ~5K tokens (recognized text)

Text is recognized on-device with the macOS Vision framework, so the default path sends only text. Claude opens an actual keyframe image only when the text isn't enough — a diagram, a chart, a UI screenshot.

Tuning: --fps, --scene-threshold, --max-frames, --no-ocr. See the README.

Notes you can actually check

The output format was rebuilt around one question: if you doubt a line, how fast can you confirm it?

Every claim carries its timestamp.

### Key Decisions
- **[12:04]** Ship v1.1 without the motion heuristic; revisit next cycle

### Action Items
- [ ] **[31:17]** Draft the migration doc — Priya · due Friday

The transcript moved out of the way. It lives in a sibling -transcript.md as timestamped lines, instead of nine thousand unattributed words buried under your action items. It's no longer printed into chat either.

Bad audio announces itself. Transcript quality is now measured — fragment rate, whisper looping, speech pace against spoken time — and a poor transcript says so instead of being summarized in the same confident voice as a clean one:

> ⚠️ Transcription quality: poor — 80% of segments were silence markers,
> fragments, or repeats. Summary may be incomplete; ggml-base.en.bin was used.

Empty states diagnose. "No decisions recorded" means something different when the transcript was too poor to find any — and only that case is fixable, so the notes tell you how.

Filenames are browsable. 2026-08-01-1402-q3-roadmap.md instead of meetey-1754049600.md. ls is now a meeting history.

Everything else

v1.0.0 v1.1.0
Decisions - [decision] - **[12:04]** [decision]
Transcript inline, also printed to chat sibling file, path only in chat
Header 2026-08-01T14:02:11.123Z → … Fri 1 Aug 2026, 2:02–2:47 PM · 45 min
Bad audio silently summarized quality callout + how to fix
Filename epoch integer date + slug
Screen content opt-in keyframes with on-device OCR

New MCP tool get_keyframes. transcribe now returns timestamped segments, exact duration read from the WAV header, the model used, and a quality assessment.

What stays local

Recording, transcription, and OCR all run on your machine. The summary is written by Claude, so transcript and OCR text goes to the API — keyframe images only when the text isn't enough to read a diagram. Audio never leaves. No meeting bot joins your call. Full breakdown in the README.

Known limitations

  • Camera-heavy calls are a poor fit for screen capture. A moving video tile changes the picture constantly and burns through the frame budget. Use it for slides and screen shares; stay on audio for faces-only discussions.
  • Capture is process-level, not tab-level. Targeting Chrome captures all Chrome audio, and with --video, everything Chrome displays.
  • English-only by default. The bundled model is base.en and transcription runs with -l en.
  • No speaker diarization. The transcript is a single stream with no per-speaker attribution.

Requirements

macOS 13+, Node.js 18+, Xcode Command Line Tools, Claude Code, Homebrew.

Source-only release, as with v1.0.0. The Swift capture binary is compiled and ad-hoc signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.

Licensed under the Apache License 2.0.

v1.0.0 — Meetey

Choose a tag to compare

@jej2k5 jej2k5 released this 31 Jul 22:26

Meetey captures meeting audio on your Mac, transcribes it locally, and turns it into structured notes — entirely inside Claude Code. No cloud service, no subscription, no audio leaving your machine.

Install

npx jej2k5/meetey install

Then open System Settings → Privacy & Security → Screen Recording, enable your terminal app, and start a new Claude Code session.

Usage

Command Hotkey What it does
/meetey start Ctrl+Shift+R Detects the running meeting app and starts recording
/meetey stop Ctrl+Shift+S Stops, transcribes, and writes notes
/meetey status Reports whether a recording is active

/meetey stop produces a summary, key decisions, and action items alongside the full transcript, saved as a .md file next to the WAV in ~/.meetey/recordings/.

What's in this release

  • Swift capture binary using ScreenCaptureKit — records app audio as 16-bit PCM WAV at 16 kHz mono, stops on SIGTERM/SIGINT or an optional --stop-after timer.
  • MCP server exposing five tools: list_apps, start_recording, stop_recording, transcribe, get_status. Registered globally in ~/.claude.json, so it's available in every Claude Code session.
  • /meetey skill with start, stop, and status subcommands.
  • meetey CLI with install, update, and status commands. status reports exactly which pieces are wired up and what to run to fix the ones that aren't.
  • Local transcription via whisper.cpp, defaulting to ggml-base.en.bin (~142 MB). Swap in small.en or large-v3-turbo-q5_0 for better accuracy by setting MEETEY_MODEL.

Supported meeting apps

App Bundle ID
Chrome (Google Meet / Teams web) com.google.Chrome
Zoom us.zoom.xos
Microsoft Teams (desktop) com.microsoft.teams

Requirements

  • macOS 13 (Ventura) or later
  • Node.js 18+
  • Xcode Command Line Tools (xcode-select --install)
  • Claude Code
  • Homebrew (installed automatically if missing)

Known limitations

  • Chrome capture is process-wide. ScreenCaptureKit captures at the process level, not the tab level, so targeting Chrome records all Chrome audio. Mute other tabs before recording.
  • No speaker diarization. The transcript is a single stream of text with no per-speaker attribution.
  • English-only by default. The bundled model is base.en, and transcription is invoked with -l en.
  • Screen Recording permission is required and must be granted to your terminal app, not to Meetey itself.

Source-only release

No prebuilt binary is attached. The Swift capture binary is compiled and ad-hoc code-signed on your machine at install time, which is what lets it hold the ScreenCaptureKit entitlement without notarization.

Licensed under the Apache License 2.0.