github epicenter-md/epicenter v7.7.0
Whispering 7.7.0: Local-First File System Storage

one day ago

This release marks a major architectural milestone in Whispering's evolution toward true local-first data ownership. Desktop now stores all your data as human-readable markdown files on your file system instead of IndexedDB.

Your recordings, transformations, and transcriptions now live as regular files on your computer. You can:

  • Open the folder and see your data directly
  • Edit metadata in any text editor
  • Back up your data by copying a folder
  • Grep through your transcriptions
  • Version control your transformations
  • Move your data between computers

This is the foundation of local-first software: your data lives in a format you control, in a location you choose, readable by standard tools.

File System Storage

Desktop now stores data as markdown files with YAML frontmatter:

~/.whispering/
├── recordings/
│   ├── abc123.md        # Metadata + transcribed text
│   └── abc123.webm      # Audio file
├── transformations/
│   └── transform-01.md
└── transformation-runs/
    └── run-001.md

Example Recording File

---
id: abc123
title: Morning Meeting Notes
timestamp: 2025-10-29T09:30:00Z
transcription_status: DONE
---

This is the transcribed content of your recording.
You can edit this in any text editor.

The audio file lives right next to it as abc123.wav. No database or proprietary format; just files.

Migration Assistant

image

When you launch this version with existing IndexedDB data, Whispering shows a toast notification with a "Migrate Now" button. The migration assistant guides you through moving your data to the file system. Migration is optional (though recommended for better performance and data ownership).

image

Why This Matters

IndexedDB is a browser technology that made sense when Whispering was web-first. But for a desktop app that values data ownership, it's the wrong tool:

  • Data is opaque (you can't see it without dev tools)
  • Backup requires special tooling
  • Export/import is complicated
  • Storage limits are unpredictable
  • You don't really own your data

File system storage fixes all of this. Your data lives in plain-text files you can read, edit, back up, and move freely. This is how local-first software should work.

This change has been in planning for months. It's a rewrite of the storage layer, and it sets us up for features like:

  • Data sync across devices (your files, your control)
  • Git integration for transformations
  • Better backup and restore
  • Command-line tooling
  • Plugins and extensions

Open Folder Buttons

New buttons on the recordings and transformations pages let you open the folder where your data lives. Click them to see your data directly in Finder/Explorer.

This might seem small, but it's fundamental: you should always know where your data is and be able to access it without the app. Transparency builds trust.

Technical Details

For those interested in the implementation:

Storage Format: Markdown files with YAML frontmatter for metadata, separate audio files with matching IDs

Batching: To speed up reads and minimize IPC calls, we bulk-read all Markdown files in the Rust layer and send their contexts as strings to the frontend, where parsing/validation occur. This keeps our performance fast by minimizing IPC calls to and from the frontend and Rust backend (e.g., one bulk-read call to markdown files instead of hundreds of IPC calls to read each file).

Migration Strategy: User-initiated migration via toast notification and dialog, with visual progress tracking and verification before cleanup

Web Compatibility: Web continues using IndexedDB. This change is desktop-only. We use dependency injection to inject the right implementation from db/web.ts or db/desktop.ts at build time.

Atomic Operations: All writes use atomic rename (write to .tmp, then rename) to prevent corruption.

Next Steps

This release was weeks of planning and implementation, and focuses on desktop storage architecture. Future releases aim to build on this foundation:

  • Sync (your settings, synced via your own cloud storage)
  • Transformation library (share and version control transformations)
  • Command-line interface
  • Plugin system

More to come!

What's Changed

  • refactor(query): consolidate query layer with entity-based namespacing by @braden-w in #883
  • feat(transcription): add persistent model manager for whisper.cpp by @braden-w in #889
  • chore: switch Claude model from opus to sonnet by @braden-w in #888
  • chore: update biome configuration to schema 2.2.6 by @braden-w in #890
  • docs(CLAUDE): specify regular merge strategy for PRs by @braden-w in #891
  • chore: update @tanstack/svelte-query to v6.0.0 by @braden-w in #892
  • fix: messed up formatting in AGENTS.md. by @Leftium in #887
  • [READY] add missing community standard files by @thisisharsh7 in #876
  • feat(whispering): add evergreen 'latest' Gemini inference API model names by @dstanley-ttech in #894
  • fix: prevent Windows console flash when executing FFmpeg commands by @braden-w in #899
  • chore: simplify and improve formatting tooling by @braden-w in #900
  • feat(settings): add proactive warnings for recording method compatibility by @braden-w in #902
  • chore: run formatter to organize imports by @braden-w in #901
  • feat(scripts): automate release workflow with commit, tag, and push by @braden-w in #903
  • refactor(rules): split AGENTS.md into domain-specific files for lazy loading by @Leftium in #906
  • fix(ci): rename GITHUB_* secrets and env vars to GH_* by @braden-w in #922
  • refactor: consolidate database layer with entity-based namespacing by @braden-w in #921
  • chore: enable experimental Svelte support in Biome 2.3 by @braden-w in #923
  • revert: disable experimental Biome Svelte support by @braden-w in #924
  • refactor(db): split service into platform-specific implementations by @braden-w in #925
  • refactor: simplify model path structure and remove redundant nesting by @braden-w in #926
  • fix(windows,transcription): prevent FFmpeg console window flash by @brummelte in #909
  • fix(ffmpeg): use shell-less executor for installed check by @brummelte in #908
  • refactor(macos-accessibility): migrate Command.create to services.command.execute by @braden-w in #927
  • Fix: Deepgram Nova-3 fails when system prompts are used due to unsupported keywords parameter by @passion8 in #895
  • feat: update Anthropic models to latest Claude 4.5 generation by @ElDataDude in #928
  • feat(landing-page): add Try Now buttons to landing page tool cards by @rupokghosh in #799
  • feat: add transform-clipboard feature with two command modes and keyboard shortcuts by @braden-w in #930
  • feat(db): implement file system storage for desktop with automatic IndexedDB migration by @braden-w in #933
  • refactor(commands): always return Ok after notifying errors by @braden-w in #932
  • refactor(db): optimize migration with sequential execution and simplified counting logic by @braden-w in #934
  • feat(transformations): add delete functionality for transformation runs by @braden-w in #935
  • fix(db): simplify transformation runs migration by @braden-w in #936
  • perf(db): optimize transformation runs queries with Rust batch reading and arktype validation by @braden-w in #938
  • fix: source AGENTS.md from CLAUDE.md. by @Leftium in #940
  • chore: remove GH action that syncs CLAUD.md. by @Leftium in #941
  • feat(MigrationDialog): add database migration tool for IndexedDB to File System by @braden-w in #943
  • feat(ci): add PR preview builds workflow by @braden-w in #942
  • refactor: replace toast with rpc.notify for migration notification by @braden-w in #944
  • fix(MigrationDialog): delete items from IndexedDB after successful migration by @braden-w in #945
  • fix(MigrationDialog): add success logging for IndexedDB deletions by @braden-w in #947

New Contributors

Full Changelog: v7.5.4...v7.7.0


Questions? Join our Discord or check the README.

Love Whispering? Star us on GitHub to show your support!

Don't miss a new epicenter release

NewReleases is sending notifications on new releases.