patro is a small, local service written in Go that turns your meeting recordings into a growing Markdown knowledge library.
It watches a folder for new videos (for example, where OBS Studio saves your recordings), sends the audio to AssemblyAI for transcription, and then asks a local AI — Kimi Code CLI or Claude Code CLI — to write structured notes. The results are saved locally and organized by topic.
You can also analyze transcripts with AssemblyAI's own LeMUR model by setting analyzer_backend: lemur in config.yaml.
knowledge/
├── topics/<slug>.md # distilled knowledge per topic, appended over time
├── meetings/<YYYY-MM-DD>-<slug>.md # full note per meeting (summary, decisions, action items, chapters)
├── transcripts/<transcript_id>.txt # raw transcript with speaker labels
└── index.md # regenerated on every run
- Linux or macOS (Windows is not supported yet)
- An AssemblyAI API key — transcription runs through their service
- Either Kimi Code CLI or Claude Code CLI installed locally, if you want to use a local AI to write the notes
- Homebrew, for the recommended install (or Go 1.26+ to build from source)
brew tap fernando143/patro https://github.com/fernando143/patro.git
brew trust fernando143/patro # recent Homebrew requires trusting third-party taps
brew install patroThen run the interactive setup wizard:
patro init
The wizard will:
- Ask for your AssemblyAI API key.
- Ask where your recordings folder is.
- Ask where to write the knowledge library.
- Ask whether you want to use Kimi or Claude as the note writer (and locate the CLI binary).
- Write the config file.
- Optionally install and start a user-level background service.
After it finishes, the service is already running. Check the logs:
- Linux:
journalctl --user -u patro -f - macOS:
log stream --predicate 'process == "patro"'(or watch the log file configured in the plist)
Check the service status:
- Linux:
systemctl --user status patro - macOS:
launchctl list | grep com.patro
The formula ships a service that runs patro serve and logs to Homebrew's var/log/patro.log:
brew services start patro
Note that the brew services environment does not include your API key. The key must come from the environment — for example, use the service installed by patro init instead (which stores the key in a systemd override.conf on Linux or in the LaunchAgent plist on macOS), or otherwise export ASSEMBLYAI_API_KEY in the service environment.
If you prefer not to use the wizard, create the canonical config file at ~/.config/patro/config.yaml. patro uses this same file for the service and TUI:
--config PATHflag (explicit override)~/.config/patro/config.yaml
An existing repository-local ./config.yaml is migrated to the canonical path
only when the canonical file does not exist yet. Once the canonical file
exists, ./config.yaml is not read implicitly.
Everything relative (inbox, library, .state/, patro.log) resolves against the directory containing the config file.
Config keys:
inbox: absolute path to the folder where recordings appearlibrary: path where the knowledge library should be writtenvideo_extensions: list of extensions that trigger processingstability_checks/stability_interval_seconds: how long to wait for OBS to finish writing a fileanalyzer_backend:kimi,claude, orlemurkimi_path/claude_path: absolute path to the CLI binary when running as a service
The AssemblyAI API key is read only from the ASSEMBLYAI_API_KEY environment variable — never put it in config.yaml:
export ASSEMBLYAI_API_KEY=<your-key>
After installation, drop or save a video into the configured inbox folder. The service will pick it up once the file stops growing and process it automatically. Stop the watcher with SIGINT/SIGTERM (Ctrl+C).
You can also run commands manually:
# Process a single file patro process /absolute/path/to/meeting.mkv # Watch the inbox forever patro serve # Preview merge candidates across every historical topic (never writes files) patro reconcile --all --dry-run # Review and selectively apply historical topic merges patro run tui # open Migrate # Run the full pipeline with fake data, no API calls (great for testing) patro process --mock /absolute/path/to/any-video.mkv patro serve --mock # Print the version patro --version
Already-processed files are tracked in .state/processed.json (next to the config file) by file name and size, so they are not reprocessed unless the file changes.
patro reconcile --all --dry-run reads every knowledge/topics/*.md, computes a deterministic merge plan with the configured embedding backend, and prints titles, paths, cosine scores, impact counts, and content hashes. It does not modify the knowledge library, state, or indexes.
Apply historical merges only through Migrate in patro run tui. Every proposal must be accepted or rejected independently (with an accept-all shortcut), followed by a final confirmation. Only accepted sources are merged and removed. Before writing, Patro verifies the preview hashes and creates a timestamped backup under .state/backups/historical-topic-migration/; stale previews are rejected without mutation. Vector and full-text indexes are rebuilt after a successful migration.
- Watch: the
servecommand watches theinboxfolder for new.mkv,.mp4,.mov, or.webmfiles. - Stabilize: because OBS writes files progressively, the service waits until the file size is unchanged across
stability_checksprobes spacedstability_interval_secondsapart. - Transcribe: the audio is sent to AssemblyAI (speaker labels, auto chapters, language detection). A raw transcript with speaker labels is saved under
knowledge/transcripts/. - Analyze: the transcript is passed to the chosen AI backend (Kimi, Claude, or LeMUR), which returns a structured JSON note.
- Write: a meeting note is saved under
knowledge/meetings/, topic files are updated underknowledge/topics/, andknowledge/index.mdis regenerated.
Use --mock mode to verify the whole pipeline without calling AssemblyAI or any AI backend:
patro process --mock /path/to/a/video.mkv
This uses deterministic fake transcripts and analysis, and still writes real output files to the knowledge library. It is the recommended way to check that the installation works.
Re-run patro init, or manually add the key to the service environment (systemctl --user edit patro on Linux, the EnvironmentVariables dict in ~/Library/LaunchAgents/com.patro.plist on macOS).
Make sure the CLI is installed and that config.yaml points to the absolute path of the binary. Systemd services do not read your shell profile, so relative names like kimi may not resolve. patro init locates the binary for you.
- Check that the
inboxpath inconfig.yamlis correct and absolute. - Check the logs.
- Make sure the video extension is in
video_extensions.
Requires Go 1.26 or newer.
The project documentation is served from docs/ with Docsify. Install the
CLI once and start the local server from the repository root:
npm install --global docsify-cli@5 docsify serve docs
git clone https://github.com/fernando143/patro.git cd patro # Source builds require Git LFS to hydrate the embedded Cybertron model. git lfs pull go build ./... go vet ./... go test ./... # Build the binary and run the smoke test (no API key needed) go build -o patro ./cmd/patro ./patro process --mock /path/to/a/video.mkv
Build a local release snapshot with GoReleaser:
goreleaser release --snapshot --clean
Git LFS is only required for source/build contributors. Homebrew and direct release installs download an ordinary Patro binary with the Cybertron model already embedded, so they do not download a separate model at runtime.
- The AssemblyAI API key is read only from the
ASSEMBLYAI_API_KEYenvironment variable, never fromconfig.yamlor the repository. - The Kimi and Claude backends shell out to your local CLI binaries with
-p. Make sure you trust the paths configured inconfig.yaml. - Writes stay under the knowledge library and
.state/directories. - Everything runs at user level; no
sudois required.