mirror-habit as an Obsidian plugin
mirror-habit now ships as an Obsidian community plugin, not just a web app. Same React core, opened in a pane inside the vault. How it’s built The React app (React 19 + Vite + Supabase) is synced into src/app/ from the main repo by scripts/sync-source.sh, then apply-patches.mjs adapts it to Obsidian — scoped styles, a lazy Supabase client, and Obsidian-safe auth links. One source, two targets (web + plugin). Offline-first: with no config, everything runs on local vault data via the plugin’s data.json — habit tracking, streaks, challenges, titles/levels. Supabase adds multi-device sync when you supply a URL + anon key. The two real gotchas Plugin view crash — the view registered as new MirrorHabitView() without passing the leaf, so opening the pane threw Cannot read properties of undefined (reading 'app'). Fix: (leaf) => new MirrorHabitView(leaf). ...