[0.5.0] - 2026-05-15
Added
- Automation API: versioned
/api/v1/recordingsnamespace for external agents (list with cursor pagination +created_since/updated_since/has_transcriptionfilters, get, transcript, metadata, audio redirect). Personal API keys (op_...prefix, HMAC-SHA256 hashed at rest keyed byAPI_TOKEN_HASH_SECRET ?? BETTER_AUTH_SECRET, revocable, withsource/name/lastUsedAtmetadata) managed from Settings. Per-IP and per-identity rate limits on/api/v1/*(1200/min IP, 600/min identity) withRetry-AfterandX-RateLimit-*headers. Signed webhooks (HMAC-SHA256,t=...,v1=...header) forrecording.synced,recording.updated,recording.deleted,transcription.completed,transcription.failedwith URL + secret encrypted at rest, exponential backoff (30s -> 6h, then dead), DB-leased worker, manual redelivery, and a deliveries inspector. Webhook target policy switches onWEBHOOKS_REQUIRE_PUBLIC_TARGETS ?? IS_HOSTED: self-host defaults permissive so docker-bridge URLs likehttp://n8n:5678/webhookkeep working. Full reference indocs/API.md(#118). - Documentation site at
/docswith Guides, Self Hosting, and Reference sections (fumadocs-mdx)./llms.txtand/llms-full.txtroutes for LLM-friendly access (#131). - Dashboard waveform player: client-side AudioContext decode on first listen, peaks cached server-side in
recordings.waveform_peaks, canvas renderer with hover timestamp and vertical playhead. Auto-decode capped at 30min with a manual "Generate waveform" button above that. Newuser_settings.player_scrubberpreference (waveform|slider) with toggle in Playback settings (#121). - Command palette (Cmd/Ctrl+K) for sync, upload, settings, theme, and recording typeahead with fuzzy search over filenames and transcript text. Inline
Transcribequick-action on audio-only rows; Cmd+Enter triggers transcribe on the highlighted row without closing the palette. Keyboard shortcuts cheatsheet (?),j/klist nav,/for search focus,,for settings (#121). - Recording list redesign: search, sort + density toggles, date-grouped rows with sticky headers, status chips (transcript / summary / in-flight), per-row delete via hover menu, infinite-scroll sentinel replacing Prev/Next, optimistic upload and delete. New
user_settings.list_densitypreference (#121). - Settings redesign with grouped sidebar nav (Providers / Plaud / Personalize / Data / Integrations / Advanced), new primitives (
SettingsSectionHeader,SettingsCard,ToggleRow), hash routing, and a master-detail mobile layout. New Storage section with usage hero, per-status breakdown bar, and top-5 largest-recordings list with deep links (#121). - Running version shown in the footer as a link to its release notes. Self-host instances also see an "update available" badge when a newer GitHub release exists (cached 5 minutes, fails silently). New optional
DISABLE_UPDATE_CHECKenv var for instances that block outbound HTTPS or want zero phone-home./api/healthresponse gains an additiveversionfield (#124, #123). - Footer "Report a bug" button and toast
[Report]action that pre-fill a GitHub issue with anerrorIdcorrelation token (and an "Email us" option on hosted). Every response with HTTP status >= 500 now carriesdetails.errorId(err_xxxxxxxx) tying the JSON envelope to a singleconsole.errorlog line, so users can quote it and support can grep logs. Connect / verify / paste-token error sites inplaud-connect-tabsmigrated totoastApiErrorso the Report action lights up on 5xx (#143). /installpage with copyable curl one-liner and version-pinned form, plus a "View raw script" escape hatch -- replaces the previous footer link that dumped raw shell into the browser. Reachable from the footer in both self-host and hosted (#125).
Changed
- API key format adopts base62 + CRC32 checksum (
op_<base62-secret><crc32>). New keys are 1 character shorter, checksum-validated before any DB lookup, so malformed input is rejected early. Existing keys continue to work unchanged (#139). - Sticky page header with consolidated user menu (email-initial avatar, inline 3-button theme control, identity block, kbd hints). Status-aware sync button replaces the separate status block + button -- label cycles
Synced 2m ago/Sync device/Syncing.../Retry syncwith tooltip carrying next-auto-sync ETA or error message (#121). - Shared imperative confirm dialog (
useConfirm()) replaces ad-hoc destructive-action confirmations across recording delete, webhook delete, custom-prompt delete, and provider delete. One dialog UI for every destructive action (#121). - React 19 cleanup pass:
forwardRef-> ref-as-prop,useContext->use(), em dashes replaced with commas/colons/periods in user-facing copy, display headings tightened tofont-semibold, hydration mismatch on locale-formatted timestamps fixed via a new<LocalTime>component, plus component splits (workstation, settings dialog, providers section, webhooks section, command palette, recording player, onboarding) to drop giant-component sizes. SEO metadata added for/and/suspended(#138). - Theme system rewritten as a thin wrapper over
next-themesto fix RadixuseIdhydration drift on Next 16.middleware.tsrenamed toproxy.tsfor the Next 16 entrypoint change. Behavior unchanged (#121). - Release pipeline hardened against tag/version drift:
scripts/release.tscreates both the release commit and the[Unreleased]cycle commit, then pushesmainand the tag atomically; the release workflow now hard-gates onpackage.jsonversion matching the pushed tag and checks out the tagged ref (#124, #123). - Footer split: minimal in-app footer (logo, AGPL, version + update badge, GitHub, hosted-only Support) for signed-in screens, and a separate hosted-only
LandingFooter(Product / Resources / Company / Legal columns + honesty rail disclaiming HIPAA / SOC 2 certification) for marketing surfaces. Self-host always sees the minimal footer (#125).
Fixed
- Install
gitin the Docker builder so fumadocs-mdx'slastModifiedplugin can read commit timestamps; without it the docs build fell back to mtime and emitted noisy warnings (#140). - Send browser
User-Agenton all Plaud API requests. Plaud's edge started 403-ing non-browser UAs, breaking sync on certain regional servers (#136, #132). - Run fumadocs-mdx codegen in the Docker builder stage instead of via
postinstall, so generated MDX bindings ship inside the runtime image and/docsdoesn't 500 on cold containers (#134). - Send
chunking_strategyfor diarization-capable transcription models, and consolidate the manual-transcribe and sync-transcribe code paths so they agree on request shape. Fixes diarize-model failures on long recordings (#128, #101). - OpenRouter transcription now routes through chat-completions (OpenRouter does not expose
/audio/transcriptions), and the provider preset ships a curated list of transcription-capable models so the picker doesn't surface chat-only models that would 404 at request time (#126, #122). - Player time label no longer resizes mid-playback.
formatTimeLike(current, reference)padscurrentTimeto matchduration's segment structure (M:SS/MM:SS/H:MM:SS) so the clock label keeps a stable width (#121). - Webhook worker no longer skews due-delivery comparisons under Bun:
nowParamis cast to::timestampto match thenext_attempt_atcolumn type (#121). - DELETE recording locks the parent row with
SELECT ... FOR UPDATEat the start of the transaction, so a concurrent transcribe or summary write can't leave orphan child rows pointing at a tombstoned recording. Sync re-checks the tombstone underFOR UPDATEbefore its update + emit, preventing delete-during-download races from resurrecting a recording (#118). - Plaud helpers (
plaudSendCode,plaudVerifyOtp,listPlaudWorkspaces,mintPlaudWorkspaceToken) parse upstream JSON defensively via a newsafeParseJson. Cloudflare WAF HTML challenge pages (and other non-JSON upstream bodies) previously escaped as rawSyntaxErrorand flattened to a genericINTERNAL_ERROR (500); they now surface as typedPLAUD_INVALID_TOKEN/PLAUD_RATE_LIMITED/PLAUD_UPSTREAM_ERROR/PLAUD_API_ERRORwith the upstream HTTP status and a 200-char body snippet indetails(#143, #142, #137).
Full changelog: CHANGELOG.md
Install: see docker-compose.yml and env.example attached below, or follow README → Quick Start.