Turn a Plaud voice recorder into a hands-free capture pipeline: recordings are
pulled from the Plaud cloud, transcribed locally with faster-whisper (no
per-minute API cost), written to Markdown with a stable YAML frontmatter
contract, and mirrored to Google Drive — organized by year/month. A companion
Claude Code skill (/boot) runs the whole thing end to end and reviews any
follow-up instructions you dictated into your recorder.
Plaud cloud → faster-whisper (local) → Markdown + YAML → Google Drive
└──────────→ /boot + /digest (Claude Code)
This repo contains two things:
| Path | What it is |
|---|---|
plaud-sync/ |
The Python pipeline (plaud-sync CLI). |
.claude/commands/boot.md |
The /boot Claude Code skill that orchestrates a one-shot run. |
No secrets ship in this repo.
.env,credentials.json, OAuth tokens, and all recorded data/transcripts live only on the machine that runs the pipeline. You supply your own — this README walks you through it.
Run this from Claude Code (it uses the authenticated gh CLI, so it works
with this private repo):
gh repo clone AlexMooreProblems/fastmaxxing ~/fastmaxxing && bash ~/fastmaxxing/install.shThat clones the repo to ~/fastmaxxing, creates the virtualenv, installs the
package, and scaffolds .env + data directories. It then prints the remaining
one-time interactive steps (Google OAuth + Plaud credentials) — those can't be
automated and are covered in Parts 1–2 below.
Already cloned? Just run
bash ~/fastmaxxing/install.sh(it's idempotent). Nogh? Usegit clone https://github.com/AlexMooreProblems/fastmaxxing.git ~/fastmaxxing && bash ~/fastmaxxing/install.sh.
The pipeline uploads to your Google Drive using an OAuth "Desktop app"
credential that you create once. The scope requested is the minimal
drive.file
— the app can only see and touch files it creates, never the rest of your
Drive.
You can use any Google/Gmail account. A dedicated account (e.g.
yourname.voicenotes@gmail.com) keeps the captured notes cleanly separated, but
your everyday account works too.
- If you want a dedicated mailbox for voice notes, create a new account at https://accounts.google.com/signup. Otherwise use an existing one.
- Stay signed into this account for the rest of Part 1.
- Go to https://console.cloud.google.com and accept the terms (the free tier is more than enough — there is no billing for this usage).
- Top bar → project dropdown → New Project. Name it
voice-notes(or anything). Create, then make sure it's the selected project.
- Go to APIs & Services → Library.
- Search Google Drive API → open it → Enable.
⚠️ This is the single most-missed step. If the Drive API isn't enabled in the same project as your OAuth credential, the first upload fails with403 accessNotConfigured. See Troubleshooting.
- APIs & Services → OAuth consent screen.
- User type: External → Create.
- Fill the required fields (app name, your email for support + developer contact). You can leave everything optional blank.
- Test users → add the Google account from step 1.1. (In Testing mode the app only needs to authorize test users — no Google verification required.)
- Save. Leave the app in Testing mode; you don't need to publish it.
- APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Application type: Desktop app. Name it anything. Create.
- Download JSON. Save it as
credentials.jsonin theplaud-sync/directory (see Part 2). This file is gitignored — never commit it.
- In https://drive.google.com (signed in as the same account), create a
folder, e.g.
Voice Notes. - Open it. The URL is
drive.google.com/drive/folders/<FOLDER_ID>. - Copy
<FOLDER_ID>— you'll paste it into.envasDRIVE_PARENT_FOLDER_ID.
You'll run the actual browser authorization (plaud-sync login-drive) in
Part 2, after the code is installed.
- macOS or Linux, Python 3.11+ (
python3 --version). - A Plaud account with at least one recording in the cloud.
- ~500 MB free disk for the Whisper model + downloads.
cd plaud-sync
# IMPORTANT: name the venv "venv" — NOT ".venv".
# On macOS a leading-dot dir is hidden and Python skips its .pth files,
# which silently breaks the editable install.
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -e ".[dev]"
# sanity check
python -c "from plaud_sync.config import get_settings; print('ok')"plaud-sync init # copies .env.example → .env and creates data dirsEdit .env:
# --- Plaud ---
PLAUD_EMAIL=you@example.com
PLAUD_PASSWORD=your-plaud-password
PLAUD_API_DOMAIN=api # api (US) | api-euc1 (EU) | api-apse1 (APAC)
# --- Google Drive ---
GOOGLE_CREDENTIALS_PATH=./credentials.json
DRIVE_PARENT_FOLDER_ID=<the folder ID from step 1.6>Leave the Whisper / behavior defaults as-is unless you have a reason to change
them (see .env.example for the full annotated list).
plaud-sync login # caches a Plaud token to data/plaud_token.json
plaud-sync login-drive # opens a browser for Google consentOn the Drive consent screen you'll see "Google hasn't verified this app" (it's
your own unpublished app) → Advanced → Go to … (unsafe) → allow. The token
is cached to data/google_token.json.
plaud-sync syncThe base Whisper model (~150 MB) downloads on the first transcription. A
healthy run ends with:
done listed=N new=N downloaded=N transcribed=N uploaded=N done=N failures={}
Check that Markdown files appear under data/transcripts/ (with a populated
## Transcript section) and that audio + transcript pairs land in your Drive
folder under YYYY/MM/.
plaud-sync watch # polls every POLL_INTERVAL_SECONDS in the foregroundFor unattended scheduling:
- cron:
*/15 * * * * cd /path/to/plaud-sync && /path/to/venv/bin/plaud-sync sync >> data/sync.log 2>&1 - systemd (Linux): copy
plaud-sync/deploy/systemd/*to~/.config/systemd/user/andsystemctl --user enable --now plaud-sync.timer.
.claude/commands/boot.md is a Claude Code
slash-command skill that runs the whole pipeline as one operation and is safe to
re-run any time. Its flow:
preflight (re-auth check + ensure folders + un-stick past failures)
→ sync (pull / transcribe / upload new recordings)
→ /digest (catalog new transcripts: summaries, action items, queued instructions)
→ verify-drive (prove every transcript is actually in Drive; auto-remediate)
→ approval (review any Claude Code instructions you dictated, before running them)
This ordering exists because of a real incident: a Drive token expired mid-run, uploads failed and were stranded, and nobody noticed until the transcripts were missing. Preflight catches a dead token before a wasted sync; verify catches anything that didn't make it after.
To use it, place this repo's .claude/commands/boot.md where your Claude Code
project can see it, adjust the service-registry paths inside boot.md to point
at your plaud-sync/ checkout, then run /boot (one-shot) or /boot --periodic
(keeps the watch loop alive for the session). The /digest step expects a
companion digest skill; boot.md documents exactly what it calls.
| Command | Purpose |
|---|---|
plaud-sync init |
Create data dirs, copy .env.example → .env. |
plaud-sync login |
Authenticate to Plaud, cache token. |
plaud-sync login-drive |
Google Drive OAuth (opens a browser). |
plaud-sync sync |
One-shot pipeline run. |
plaud-sync watch |
Loop sync every POLL_INTERVAL_SECONDS. |
plaud-sync preflight |
Pre-sync health checks (exit 2 ⇒ re-auth needed). |
plaud-sync verify-drive [--fix] |
Confirm every transcript is in Drive; --fix backfills. |
plaud-sync status |
Table of recordings by status. |
plaud-sync retry --id <plaud_id> |
Reset a FAILED_* row to its prior status. |
plaud-sync upload-digest |
Mirror a single Markdown file (the digest) to Drive. |
plaud-sync transcribe <path> |
Transcribe an arbitrary local audio file (utility). |
These were all hit during the original bring-up — apply them up front.
ModuleNotFoundError: plaud_syncafter install — your venv directory starts with a dot. macOS hides dotted dirs and Python skips their.pthfiles. Rebuild asvenv/(no leading dot).403 accessNotConfiguredon first upload — the Drive API isn't enabled in the same Cloud project as your OAuth client. Enable it (step 1.3), wait ~30s, thenplaud-sync retry --id <id>(or re-runsync).syncreportslisted=0despite having recordings — usually a Plaud region mismatch; confirmPLAUD_API_DOMAINmatches your account region.- A transcript's
## Transcriptis empty — the recording was still finalizing on Plaud's side (wait_pull=1) when listed. The pipeline skips unready recordings and logsskipping unready recording <id>; they sync automatically on a later run once the device finishes uploading. - Drive consent shows "unverified app" — expected for your own unpublished app. Advanced → Go to … (unsafe) → allow.
More detail (Plaud API specifics, the state machine, a full purge/reset
procedure) lives in plaud-sync/setup-kit/PROCEDURE.md.
By design, so nothing sensitive is ever shared:
plaud-sync/.envandcredentials.json— your live secrets.plaud-sync/data/— OAuth tokens, the SQLite state DB, and all recorded audio/transcripts.plaud-sync/outputs/— generated digests and notes.
All of the above are gitignored. Supply your own per Parts 1–2.