meetspec
Turn client calls into requirements you can build against, without the audio ever leaving your machine.
meetspec transcribes meeting recordings (Zoom, Google Meet, Microsoft Teams, Webex, or any audio/video file) locally with faster-whisper, then hands the transcript to your AI coding agent (Claude Code, Codex, Cursor, Gemini CLI, Copilot, …) with playbooks to write meeting notes, propose requirements, draft a confirmation email for the client, implement approved requirements, and check that the code actually does what was agreed.
Recording ──► meetings transcribe ──► process-meeting ──► you review, client confirms
(local, offline) notes, REQ files, │
confirmation email ▼
meetings status ◄── implement-req REQ-012 ◄── approved requirement
req-check code + tests linked by ID
Contents
- Features
- Install
- Quick start
- Commands
- AI agents
- Requirement files
- Choosing a model
- Recording tips by platform
- Privacy
- Troubleshooting
- Contributing
- License
Features
- Local transcription. Audio is processed on your computer. After the one-time model download, transcription needs no network.
- Any meeting platform. Zoom, Google Meet, Teams, Webex, Riverside, Discord, a phone voice memo: if it is an audio or video file, it works. Meeting dates are read from Zoom, Meet and Teams file names.
- Speakers by name. With per-person audio tracks (Zoom, Riverside, Zencastr, Craig for Discord, …), each line is labelled with who said it. No guessing.
- Progress you can see. Download progress in MB and transcription progress against the length of the call.
- Requirements as files. Each requirement is a Markdown file with a status, a client confirmation flag and acceptance criteria.
- Code linked to requirements.
REQ-012in a comment or test name ties code to a requirement;meetings statusreports what is missing. - Works with any AI agent. An
AGENTS.md, step-by-step playbooks, versioned JSON for transcripts and status, and--jsonoutput on the CLI. Claude Code skills and a Cursor rule are installed for you. - Stays out of your project's git. Everything lives in a
.meetings/folder hidden through.git/info/exclude, on your machine only. The project's.gitignoreis never touched. - macOS, Windows and Linux.
Install
You need git and uv. uv installs Python for you if it is missing.
1. Install uv (once per computer)
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
2. Install meetspec
uv tool install meetspec
This adds the meetings command. Check it with meetings --version.
It is on PyPI, so pipx install meetspec or pip install meetspec work too. To try the latest unreleased code: uv tool install git+https://github.com/exarth-labs/meetspec. Releases are listed on the releases page.
Update
To get the latest version:
uv tool upgrade meetspec
Then run meetings install again in each project to refresh its playbooks, skills and templates.
Uninstall
uv tool uninstall meetspec. Downloaded models stay in the Hugging Face cache (~/.cache/huggingface/hub); delete them there if you want the space back.
To remove it from a project, delete .meetings/ (after backing up anything you need), the three folders in .claude/skills/ (process-meeting, implement-req, req-check) and .cursor/rules/meetings.mdc, then the # meetspec (local only) lines from .git/info/exclude.
Quick start
cd ~/code/client-project
meetings install # once per project
Add the client's names, product names and technical terms to .meetings/glossary.md (one per table row). They are passed to the speech model so they come out spelled right. Then transcribe:
meetings transcribe "~/Downloads/Kickoff (2026-10-13 18:19 GMT+5).mp4"
# → .meetings/transcripts/2026-10-13-kickoff.md and .json
Then ask your AI agent, inside the project:
| Agent | Say |
|---|---|
| Claude Code | /process-meeting .meetings/transcripts/2026-10-13-kickoff.json |
| Cursor | "Process the meeting in .meetings/transcripts/2026-10-13-kickoff.json" |
| Codex, Gemini CLI, others | "Follow .meetings/AGENTS.md to process .meetings/transcripts/2026-10-13-kickoff.json" |
Review the notes and proposed requirements it wrote in .meetings/, send the drafted confirmation email, and mark confirmed requirements approved. Then ask it to implement one: /implement-req REQ-001 in Claude Code, or "implement REQ-001" elsewhere.
Commands
meetings install [project]
Sets up a project. Run it in the project folder (or pass the path). It must be a git repository.
| Creates | Purpose |
|---|---|
.meetings/requirements/ |
Requirement files and their template |
.meetings/meetings/ |
Meeting notes and confirmation emails |
.meetings/transcripts/ |
Transcripts |
.meetings/glossary.md |
Names and technical words, for better spelling |
.meetings/README.md |
How the folder works, for people |
.meetings/AGENTS.md |
How the folder works, for AI agents |
.meetings/playbooks/ |
Step-by-step instructions for each task |
.claude/skills/ |
The playbooks as Claude Code skills |
.cursor/rules/meetings.mdc |
A Cursor rule pointing to .meetings/AGENTS.md |
All of it is added to .git/info/exclude, so git ignores it on this machine only. Running it again updates the templates, playbooks, skills and rule, and never touches your requirements, notes, transcripts or glossary.
meetings transcribe <input>
Transcribes any audio or video file (.m4a, .mp3, .wav, .flac, .ogg, .webm, .mp4, .mkv, .mov, …), or a folder containing the recording.
- One file, or a folder with one recording in it: every line gets one label (the audio-only file is preferred when a folder has both audio and video).
- Per-person tracks: lines are labelled with each person's name, taken from the file names. A Zoom folder with an
Audio Recordsubfolder is detected automatically; for any other folder of per-person tracks, add--per-speaker.
Output goes to .meetings/transcripts/ inside a project, or ./transcripts/ elsewhere: a readable .md and a .json for agents and tools. The file name starts with the meeting date, read from the recording's name when it has one (Zoom, Google Meet and Teams names do) and otherwise from the file's modified date. Transcribing the same recording again replaces its transcript; a different recording that would get the same name gets a -2 suffix.
| Option | Default | |
|---|---|---|
--per-speaker |
The folder holds one audio file per person | |
--model |
large-v3 |
See Choosing a model |
--language |
en |
Language code (de, ur, …), or auto to detect. Use auto for non-English or mixed-language calls |
--prompt |
terms in glossary.md |
Names and terms used in the call; improves their spelling. --prompt "" uses none |
--speakers |
JSON file mapping detected names to labels, e.g. {"John Smith": "Client - John"} |
|
--label |
Speaker |
Label when speakers are not separated |
--device |
auto |
cpu or cuda |
--compute-type |
int8 on CPU |
e.g. float16 on GPU |
--out |
Output folder | |
--no-vad |
Keep silent parts (try this if speech is missing) | |
--json |
Print the result (file paths, line count, speakers) as JSON |
meetings status
Scans the project for requirement IDs and writes .meetings/STATUS.md: every requirement with its status, client confirmation, code and test references, and problems such as:
- code that references a requirement that does not exist
- a requirement marked
donewith no code or no tests - code written for a requirement that is still
proposedor alreadydropped - approved work not yet confirmed by the client
--stdout prints the report instead; --json prints it as JSON without writing anything; --check exits with status 1 when there are errors. It checks that code is linked, not that it is correct. That is what the req-check playbook is for.
AI agents
Everything an agent needs is in plain files, so any coding agent can do the work.
| Playbook | What the agent does |
|---|---|
process-meeting |
Writes the meeting note, proposes new and changed requirements (each citing a transcript timestamp), lists open questions, and drafts a client confirmation email. It never approves anything itself. |
implement-req |
Refuses unapproved requirements, plans the work against the acceptance criteria, builds on a branch, links code and tests to the ID, and reports each criterion as met or not. |
req-check |
Read-only review of whether the code really meets each requirement's acceptance criteria. Use it before a client update or release. |
How each agent finds them
| Agent | How |
|---|---|
| Claude Code | Installed as skills: /process-meeting, /implement-req, /req-check. |
| Cursor | Installed rule .cursor/rules/meetings.mdc lets Cursor's agent load .meetings/AGENTS.md when a request is about meetings, transcripts or requirements. To be sure, mention .meetings/AGENTS.md in your request. |
| Codex, Gemini CLI, Copilot, Aider, others | Tell it to follow .meetings/AGENTS.md. To make that automatic, add one line to your own instructions file (AGENTS.md, GEMINI.md, …): For client meetings and REQ-### requirements, follow .meetings/AGENTS.md. |
| ChatGPT or Claude in the browser | Upload the transcript .md (or .json) together with the playbook .md you want it to follow. |
For tool builders, the formats are stable and versioned:
- Transcripts:
.meetings/transcripts/*.jsonwith"schema": "meetspec/transcript/v1", ametablock andsegmentsof{start, end, speaker, text}(seconds from the start of the recording). - Status:
meetings status --jsonwith"schema": "meetspec/status/v1", asummary, every requirement with its code and test references, andproblems. - CLI: progress goes to stderr, results to stdout.
meetings status --checkexits with 1 when there are errors.
The full description an agent reads is in src/meetings/kit/AGENTS.md.
Transcripts are machine-made. The playbooks treat names, numbers and dates as uncertain and turn anything unclear into a question for the client rather than a requirement.
Requirement files
.meetings/requirements/REQ-012-invoice-export.md:
---
id: REQ-012
title: Export invoices as CSV
status: approved # proposed | approved | in-progress | done | dropped
client_confirmed: yes
confirmed_on: 2026-10-15
source: .meetings/meetings/2026-10-13-kickoff.md [00:14:32]
owner: Ikram
---
# REQ-012: Export invoices as CSV
## What the client wants
...
## Acceptance criteria
- [ ] Given a month is selected, when I export, then only that month's invoices are included
Link code to it with the ID in a comment at the feature's entry point and in at least one test name: // REQ-012, it("REQ-012 …") or def test_req_012_…().
| Status | Meaning | Set by |
|---|---|---|
proposed |
Heard in a meeting, not reviewed | The agent (process-meeting) |
approved |
Reviewed and confirmed by the client | A person |
in-progress |
Being built | Developer or the agent (implement-req) |
done |
Built, tested and reviewed | A person |
dropped |
No longer wanted | A person |
Choosing a model
Models download once on first use (to ~/.cache/huggingface/hub, or %USERPROFILE%\.cache\huggingface\hub on Windows) and are shared by every project.
| Model | Size | Notes |
|---|---|---|
large-v3 |
~3 GB | Most accurate, any language. Slow on CPU. |
turbo |
~1.6 GB | Close to large-v3, much faster, any language. |
distil-large-v3 |
~1.5 GB | Fast and accurate, English only. |
small, base, tiny |
75–500 MB | Quick tests. Expect mistakes. |
On a laptop without an NVIDIA GPU, start with --model distil-large-v3 for English calls, or --model turbo --language auto for other or mixed languages, and compare against large-v3 on one real call.
Recording tips by platform
Any audio or video file works. Per-person tracks give you speaker names; a single mixed recording gives you one label for everyone, and the agent infers who said what from context.
| Platform | How to get the recording | Speakers by name |
|---|---|---|
| Zoom | Settings → Recording → Local recording → tick Record a separate audio file for each participant. Pass the meeting's folder (usually ~/Documents/Zoom/<date> <topic>). |
Yes, automatically |
| Google Meet | Recordings are saved to the organiser's Google Drive (Meet Recordings). Download the .mp4 and pass it. |
No |
| Microsoft Teams | Open the recording from the meeting chat or OneDrive/SharePoint, download the .mp4 and pass it. |
No |
| Webex, GoTo, others | Download the cloud or local recording and pass the file. | No |
| Riverside, Zencastr, SquadCast | Download the separate per-participant audio tracks into one folder and pass it with --per-speaker. |
Yes |
| Discord (Craig bot) | Download the multi-track ZIP, unzip it, and pass the folder with --per-speaker. |
Yes |
| In person / phone | Any voice-memo app. Pass the .m4a / .mp3. |
No |
If the track names are not people's names, map them with --speakers names.json, e.g. {"1-jdoe": "Client - John"}.
Privacy
meetingsitself reads recordings and writes transcripts only on your computer. Its only network access is downloading the model from Hugging Face the first time.- Your AI agent is different: when it follows a playbook, it reads the transcript like any other project file and sends it to its provider (Anthropic, OpenAI, …) under your account's terms. Only use agents you are allowed to share client conversations with.
.meetings/is excluded from git, so transcripts and notes are never committed by accident. That also means they are not backed up. Back the folder up yourself if you need to.- Recording laws differ by country and state, and some require everyone's consent. Ask at the start of every call.
See SECURITY.md to report a vulnerability.
Troubleshooting
Operation not permitted on macOS. macOS blocks terminal apps from Documents, Desktop and Downloads (where Zoom and browsers save recordings) until you allow it: System Settings → Privacy & Security → Files and Folders → your terminal app (Terminal, iTerm, VS Code) → enable the folder. Quit and reopen the app. Or copy the recording somewhere else.
Transcription is slow. Use a smaller model (see above). On CPU the default int8 compute type is already the fastest.
Windows with an NVIDIA GPU fails to start. GPU mode needs the CUDA 12 and cuDNN 9 libraries. Install them, or run with --device cpu.
"You are sending unauthenticated requests to the HF Hub". Harmless. Set HF_TOKEN to a free Hugging Face token if downloads are slow.
Words or names are wrong. Add them to .meetings/glossary.md and transcribe again; the glossary is used as the prompt automatically and also helps the agent spot mishearings.
The transcript is in the wrong language or reads like a translation. The default language is English. Pass --language auto, or the right code such as --language ur.
Stopped with Ctrl+C or the download broke. Run the same command again; a partly downloaded model resumes.
No .meetings/ folder here. Run meetings install in the project root first.
Contributing
Bug reports and pull requests are welcome. See CONTRIBUTING.md.
License
Metadata
Release files for meetspec 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| meetspec-0.1.1.tar.gz | 65.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| meetspec-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 100.4 kB
Release files / meetspec-0.1.1.tar.gz
| Download URL | meetspec-0.1.1.tar.gz |
|---|---|
| Size | 65.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
98745e31bb185b40d5689f2688d2d03167051d4f052c17d5d17f36035751fd65
|
|
BLAKE2b-256 checksum How to use checksums |
220d1e52d05119945b2d97541c46174fac1cabedb099d499c7c6e249ed82dba2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / meetspec-0.1.1-py3-none-any.whl
| Download URL | meetspec-0.1.1-py3-none-any.whl |
|---|---|
| Size | 35.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
16917516e7058fe35afcb7427d3bcca20311ac54f0e4cf8000df640cfa8cdb11
|
|
BLAKE2b-256 checksum How to use checksums |
af0096a6a9752f270a7f7a5c324310e1545d5ddeab9ef909d08e8bb495e593d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log