max / audiofiles
6 files changed,
+68 insertions,
-15 deletions
| @@ -4,7 +4,7 @@ All notable changes to audiofiles will be documented in this file. | |||
| 4 | 4 | ||
| 5 | 5 | Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | |
| 6 | 6 | ||
| 7 | - | ## [0.4.0] — 2026-04-16 | |
| 7 | + | ## [0.4.0] - 2026-04-16 | |
| 8 | 8 | ||
| 9 | 9 | ### Added | |
| 10 | 10 | - Trial mode: use the app without a license key with a 30-day countdown | |
| @@ -12,14 +12,14 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version | |||
| 12 | 12 | - Trial status display in Settings > License section | |
| 13 | 13 | - Trial state persisted to `~/.config/audiofiles/trial.json` | |
| 14 | 14 | ||
| 15 | - | ## [0.3.6] — 2026-04-16 | |
| 15 | + | ## [0.3.6] - 2026-04-16 | |
| 16 | 16 | ||
| 17 | 17 | ### Changed | |
| 18 | 18 | - Monorepo path dependency restructure (MNW shared libs) | |
| 19 | 19 | - Audit Run 14: test coverage, refactoring, cleanup | |
| 20 | 20 | - Added CONTRIBUTING.md with project coding patterns | |
| 21 | 21 | ||
| 22 | - | ## [0.3.5] — 2026-04-13 | |
| 22 | + | ## [0.3.5] - 2026-04-13 | |
| 23 | 23 | ||
| 24 | 24 | ### Added | |
| 25 | 25 | - SSE push notifications for real-time sync events | |
| @@ -44,7 +44,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version | |||
| 44 | 44 | - Blob validation on sync upload/download | |
| 45 | 45 | - OAuth state parameter verification | |
| 46 | 46 | ||
| 47 | - | ## [0.3.0] — 2026-03-28 | |
| 47 | + | ## [0.3.0] - 2026-03-28 | |
| 48 | 48 | ||
| 49 | 49 | First beta-ready release. | |
| 50 | 50 | ||
| @@ -61,7 +61,7 @@ First beta-ready release. | |||
| 61 | 61 | - Waveform visualization | |
| 62 | 62 | - Collections for organizing samples | |
| 63 | 63 | - Audio analysis: spectral features, BPM, key detection, MFCC extraction | |
| 64 | - | - 16 bundled color themes | |
| 64 | + | - Bundled color themes (see `crates/audiofiles-browser/themes/`) | |
| 65 | 65 | - macOS, Windows, and Linux builds | |
| 66 | 66 | ||
| 67 | 67 | ### Fixed |
| @@ -15,7 +15,7 @@ audiofiles/ (workspace root) | |||
| 15 | 15 | audiofiles-rhai/ # Device plugin runtime (TOML manifests + Rhai hooks) | |
| 16 | 16 | audiofiles-train/ # ML classifier training (dev-only binary) | |
| 17 | 17 | audiofiles-bench/ # Performance benchmarks | |
| 18 | - | plugins/devices/ # Bundled device profiles (SP-404, MPC, etc.) | |
| 18 | + | audiofiles-rhai/plugins/bundled/ # Bundled device profiles (SP-404, MPC, etc.) | |
| 19 | 19 | dist/ # Build scripts for macOS, Windows, Linux | |
| 20 | 20 | ``` | |
| 21 | 21 |
| @@ -4,7 +4,7 @@ A sample manager with content-addressed storage and a virtual file system. Stand | |||
| 4 | 4 | ||
| 5 | 5 | ## Prerequisites | |
| 6 | 6 | ||
| 7 | - | - **[Rust](https://www.rust-lang.org/)** (stable toolchain, 2021 edition) | |
| 7 | + | - **[Rust](https://www.rust-lang.org/)** (stable toolchain, 2024 edition) | |
| 8 | 8 | ||
| 9 | 9 | No platform-specific audio libraries are required. Audio decoding uses [Symphonia](https://github.com/pdeljanov/Symphonia) (pure Rust), SQLite is bundled via [rusqlite](https://github.com/rusqlite/rusqlite), and the standalone app uses [cpal](https://github.com/RustAudio/cpal) for system audio output. | |
| 10 | 10 | ||
| @@ -80,7 +80,7 @@ Shared libraries from `../MNW/shared/`: [theme-common](../MNW/shared/theme-commo | |||
| 80 | 80 | ### Infrastructure | |
| 81 | 81 | - **Cloud sync** -- cross-device sync of metadata, tags, and VFS via SyncKit (E2E encrypted, ChaCha20-Poly1305 + Argon2) | |
| 82 | 82 | - **OTA updates** -- background update checker with consent dialog | |
| 83 | - | - **17 bundled themes** -- dark, light, and high-contrast variants in TOML format | |
| 83 | + | - **Bundled themes** -- dark, light, and high-contrast variants in TOML format (see `crates/audiofiles-browser/themes/`) | |
| 84 | 84 | - **Audio formats** -- WAV, FLAC, MP3, OGG, AIFF (via Symphonia, pure Rust) | |
| 85 | 85 | - **Platforms** -- macOS, Windows, Linux (standalone, no backend required) | |
| 86 | 86 | ||
| @@ -93,7 +93,7 @@ Shared libraries from `../MNW/shared/`: [theme-common](../MNW/shared/theme-commo | |||
| 93 | 93 | | Training binary | `crates/audiofiles-train/` | | |
| 94 | 94 | | UI components | `crates/audiofiles-browser/src/` | | |
| 95 | 95 | | Desktop app shell | `crates/audiofiles-app/src/` | | |
| 96 | - | | Device export profiles | `plugins/bundled/` | | |
| 96 | + | | Device export profiles | `crates/audiofiles-rhai/plugins/bundled/` | | |
| 97 | 97 | | Architecture | `docs/architecture.md` | | |
| 98 | 98 | ||
| 99 | 99 | ## License |
| @@ -108,7 +108,7 @@ Pitch shifting uses semitone-based ratio calculation: `2^(semitone_offset / 12) | |||
| 108 | 108 | ||
| 109 | 109 | ## Theme System | |
| 110 | 110 | ||
| 111 | - | The browser supports multiple color themes via a 14-slot palette (4 background, 3 foreground, 6 accent, 1 border). Themes are defined as TOML files with `[meta]`, `[background]`, `[foreground]`, `[accent]`, and `[border]` sections. 16 themes are bundled at compile time (Tokyo Night, Catppuccin Mocha/Latte, Dracula, Nord, Ayu Light, Flatwhite, Neobrute, High Contrast, Everforest, Gruvbox Dark/Light, Kanagawa, Rosé Pine/Dawn, Solarized Dark, plus the default audiofiles theme). Users can add custom themes to `<config>/audiofiles/themes/` which override bundled themes by ID. | |
| 111 | + | The browser supports multiple color themes via a 14-slot palette (4 background, 3 foreground, 6 accent, 1 border). Themes are defined as TOML files with `[meta]`, `[background]`, `[foreground]`, `[accent]`, and `[border]` sections. Bundled themes live in `crates/audiofiles-browser/themes/` and are compiled in at build time; users can add custom themes to `<config>/audiofiles/themes/` which override bundled themes by ID. | |
| 112 | 112 | ||
| 113 | 113 | The active theme is stored in a global `RwLock<ThemeColors>`. Public accessor functions (e.g., `bg_primary()`, `text_secondary()`, `accent_blue()`) read through the lock. Derived colors (row stripes, selection highlights, hover states) are computed by linear interpolation between base palette slots. | |
| 114 | 114 |
| @@ -9,7 +9,7 @@ audiofiles is a standalone desktop sample manager. It stores samples by content | |||
| 9 | 9 | ## Design | |
| 10 | 10 | ||
| 11 | 11 | - **Brand:** "audiofiles/" in Recursive Mono Bold. Short form: "af/" | |
| 12 | - | - **Default theme:** Bold black and white (pure #000000 background, #ffffff text, sharp system accent colors). 17 bundled themes including dark, light, and high-contrast variants. | |
| 12 | + | - **Default theme:** Bold black and white (pure #000000 background, #ffffff text, sharp system accent colors). Bundled themes (dark, light, and high-contrast variants) live in `crates/audiofiles-browser/themes/`. | |
| 13 | 13 | - **Typography:** Recursive Mono Bold for the logo; egui system font for all UI text. | |
| 14 | 14 | ||
| 15 | 15 | ## Features | |
| @@ -41,7 +41,7 @@ audiofiles is a standalone desktop sample manager. It stores samples by content | |||
| 41 | 41 | - Musical key detection | |
| 42 | 42 | - Spectral: centroid, flatness, rolloff, zero-crossing rate, onset strength | |
| 43 | 43 | - Loop detection: cross-correlation + beat alignment | |
| 44 | - | - Classification: rule-based into 12 categories | |
| 44 | + | - Classification: rule-based into 16 categories | |
| 45 | 45 | - Waveform generation: downsampled peak pairs for display | |
| 46 | 46 | - Background worker thread (non-blocking UI) | |
| 47 | 47 | - Progress bar with cancel support | |
| @@ -177,7 +177,7 @@ Two-layer ML system: rule-based broad classifier (Layer 1) + 200-tree Random For | |||
| 177 | 177 | - Escape: close dialog / clear search | |
| 178 | 178 | ||
| 179 | 179 | ### Themes | |
| 180 | - | - 17 bundled themes (audiofiles default + 16 community themes) | |
| 180 | + | - Bundled themes (audiofiles default + community themes; see `crates/audiofiles-browser/themes/`) | |
| 181 | 181 | - Dark: audiofiles, Tokyo Night, Catppuccin Mocha, Dracula, Nord, Gruvbox Dark, Rose Pine, Everforest, Solarized Dark, Kanagawa | |
| 182 | 182 | - Light: Catppuccin Latte, Ayu Light, Flatwhite, Neobrute, Gruvbox Light, Rose Pine Dawn | |
| 183 | 183 | - High Contrast: High Contrast | |
| @@ -218,7 +218,7 @@ Music Production, Samples, Audio, Sample Manager, Hardware Sampler, Rust | |||
| 218 | 218 | ||
| 219 | 219 | ### Tech Stack | |
| 220 | 220 | ||
| 221 | - | - **Language:** Rust (2021 edition), zero `unsafe` in production code (17 justified FFI blocks in platform drag-out) | |
| 221 | + | - **Language:** Rust (2024 edition), zero `unsafe` in production code (17 justified FFI blocks in platform drag-out) | |
| 222 | 222 | - **Audio Decoding:** Symphonia 0.5.5 | |
| 223 | 223 | - **Analysis:** stratum-dsp 1.0 (BPM/key), bs1770 (LUFS), realfft 3.5 (spectral) | |
| 224 | 224 | - **Database:** SQLite via rusqlite 0.31 (bundled) | |
| @@ -236,7 +236,7 @@ Tests cover: database, store, VFS, tags, analysis (incl. ML classifier), search, | |||
| 236 | 236 | ||
| 237 | 237 | ### Status | |
| 238 | 238 | ||
| 239 | - | All pre-beta phases complete. Audit grade A. v0.3.0, standalone-only. License key activation required. | |
| 239 | + | License key activation required. | |
| 240 | 240 | ||
| 241 | 241 | --- | |
| 242 | 242 |
| @@ -0,0 +1,53 @@ | |||
| 1 | + | # audiofiles — Todo | |
| 2 | + | ||
| 3 | + | **Last updated:** 2026-05-31 late evening (post-launch-eve fuzz pass). | |
| 4 | + | ||
| 5 | + | ## Status | |
| 6 | + | ||
| 7 | + | 5 launch-blocker fixes landed in commit `c18d7e1` (unpushed). Compile clean; preferences (6/6) + export (56/56) targeted tests green. See commit message for the fix list. | |
| 8 | + | ||
| 9 | + | ## Open before launch (Monday 2026-06-01) | |
| 10 | + | ||
| 11 | + | - [ ] Push `main` to all remotes (commit `c18d7e1`) | |
| 12 | + | - [ ] Build signed binaries per platform (macOS arm64 primary; iOS per launch-platforms policy; Win/Linux unsupported per policy) | |
| 13 | + | - [ ] Notarize macOS DMG; verify with `spctl -a -vvv -t install` | |
| 14 | + | - [ ] Cargo.toml version bump for launch release; CHANGELOG entry | |
| 15 | + | - [ ] First-launch smoke test on a clean macOS account: activation → vault setup → drop a folder → see no emoji prefixes → open About (Cmd+I) → toggle update check off → confirm preferences.json written | |
| 16 | + | ||
| 17 | + | ## Run #9 deferrals (Phase 4) | |
| 18 | + | ||
| 19 | + | ### Trust / data integrity (creator-fuzz) | |
| 20 | + | - [ ] **Export silently strips BWF / iXML / smpl / cue / ID3 chunks on conversion.** `encode.rs` / `encode_aiff.rs` write only fmt+data / COMM+SSND. At minimum, warn on the Configure step when format != Original. Long-term: round-trip BWF `bext`, `smpl` loop points, `cue ` markers in the WAV encoder. | |
| 21 | + | - [ ] **Format support gaps.** `AUDIO_EXTENSIONS` (`crates/audiofiles-core/src/util.rs:6`) excludes `.m4a`/`.alac`, `.opus`, `.w64`, `.caf`, `.bwf`. Either expand or surface skip count on import with extension breakdown. | |
| 22 | + | - [ ] **Export not atomic.** `runner.rs` writes directly to dest; partial files survive a mid-write kill. Switch to `dest.tmp` + `fs::rename` on success; cleanup tmp on error. | |
| 23 | + | - [ ] **Edit-result import then `remove_file` not atomic across processes.** `state/import_workflow.rs:1288-1297` deletes temp before VFS link is confirmed. | |
| 24 | + | - [ ] **`SampleStore::remove` deletes DB row first, then file — orphan blob on file-delete failure.** `store.rs:191`. | |
| 25 | + | ||
| 26 | + | ### UX polish (use-fuzz) | |
| 27 | + | - [ ] **Preserve form fields on signup-style error swaps.** (Not applicable to audiofiles per se, but the pattern — re-render the wizard step with user input — would apply if any wizard step ever fails inline.) | |
| 28 | + | - [ ] **Sort-arrow glyphs U+25B2 / U+25BC** in `file_list.rs::draw_sort_header` are documented exceptions to the no-emoji rule. Get explicit user sign-off or replace with text ("asc" / "desc"). | |
| 29 | + | - [ ] **First-launch welcome cannot be dismissed inline** — only disappears after successful import or "Show welcome" toggle. Add a small "Dismiss" link near the bottom of `file_list.rs:44-96`. | |
| 30 | + | - [ ] **Toolbar buttons have no visual hierarchy** — Import, Export, Sync, Settings, Help all render identically. When library is empty, paint Import with `widgets::primary_button` styling. | |
| 31 | + | - [ ] **Error toast / status copy nits**: `activation.rs:119` "Activating..." should use U+2026 (`…`); `library.rs:100` "Locate failed: {e}" is terse — make it "Could not locate sample on disk — {e}". | |
| 32 | + | ||
| 33 | + | ### Rust quality (rust-fuzz) | |
| 34 | + | - [ ] **`Result<_, String>` leaks past the typed-error wall** in `crates/audiofiles-browser/src/state/playback.rs:9,20`, `crates/audiofiles-app/src/midi.rs:35`, `crates/audiofiles-app/src/license.rs:209`. Fold into `PreviewError` / `MidiError` / `LicenseError`. | |
| 35 | + | - [ ] **`unwrap()` after `is_none()` check** at `crates/audiofiles-browser/src/backend/direct.rs:571, 595` — idiomatic refactor to `idx.get_or_insert_with(...)`. | |
| 36 | + | - [ ] **Hand-rolled `synckit.toml` parser** at `crates/audiofiles-app/src/main.rs:134-149` — `toml` is already a workspace dep; replace with `toml::from_str::<HashMap<String, String>>()`. | |
| 37 | + | - [ ] **Dependency duplication** — `cargo tree -d` shows four `windows-core` versions (0.54/0.56/0.58/0.62) and two `objc2-foundation` (0.2.2/0.3.2). Bloats Win/macOS binaries; bump `tray-icon` / `objc2` callers in sync. | |
| 38 | + | ||
| 39 | + | ### Repo hygiene (launchplan §2.3) | |
| 40 | + | - [ ] Remove `crates/audiofiles-app/tests/harness/mod.rs.bak` if it ever reappears (deleted this session as part of the fix commit). | |
| 41 | + | - [ ] Audit `docs/` for stale plans; either delete or mark complete. | |
| 42 | + | - [ ] `CONTRIBUTING.md` walkthrough against current build commands. | |
| 43 | + | ||
| 44 | + | ## Audit deltas to revisit | |
| 45 | + | ||
| 46 | + | - [ ] **In-app updater toggle takes effect on next launch only.** Current implementation persists the pref + skips spawn at startup but doesn't tear down the already-spawned tokio task at runtime. Either accept (cheap, restart-required) or wire a `tokio::sync::watch` cancel signal into the check loop. | |
| 47 | + | ||
| 48 | + | ## Future enhancements (not blocking) | |
| 49 | + | ||
| 50 | + | - [ ] Move About modal trigger into a Help menu (toolbar Help button is already there but routes only to keyboard-shortcuts overlay; add a sub-action for About). | |
| 51 | + | - [ ] `Cmd+,` for preferences as macOS users will expect (currently only Cmd/Ctrl+I → About → toggle). | |
| 52 | + | - [ ] SyncKit upload contract audit — what exactly gets uploaded vs encrypted; verify E2E boundary; audit `crates/audiofiles-sync/src/service/upload.rs`. | |
| 53 | + | - [ ] Database migration safety review — 12 inline migrations in `db.rs` not audited this pass. |