What shipped, when, and why.
Thirteen shipped entries between v0.4.0 and v0.6.7. Dates are local (Asia/Bangkok). Major versions reset the public API; minor versions add capability; patches fix regressions.
Pulse — release history.
Major versions ship a new platform surface. Minor versions tighten existing ones. Patches land without ceremony.
-
patch v0.6.7 · Windows desktop — R100 build infra + R115 SPDX headers
Windows desktop bumped 0.6.5 to 0.6.7 with R100 build-infra fixes and R115 R114-audit quick win #1. R100 prebuild-kill.ps1 now kills orphan ollama.exe so a re-build with a running local Ollama no longer deadlocks the linker. Cargo.lock self-version regenerated to 0.6.5 (was tracking 0.6.4). R115 quick win #1 lands Apache 2.0 SPDX-License-Identifier headers on the source files that were previously missing them — 100% SPDX coverage on .ts, .tsx, .rs, .svelte now. R114 hard-rules audit: 8/12 strict, 10/12 targeted with the R115 quick wins. R100 polish that already shipped: low_confidence UI consumer and tree-sitter Smart Engine. Android stays on v0.6.6 — v0.6.7 is a Windows-only patch.
- R100 fix: prebuild-kill.ps1 sends SIGKILL to orphan ollama.exe before the build starts. Resolves the R100 build lock — the v0.6.5 chain stalled because the previous script did not clean up Ollama on its way out, so a re-build with a running local Ollama would deadlock the linker.
- R100 follow-up: Cargo.lock self-version regenerated to 0.6.5 by cargo (was tracking 0.6.4). Brings the lockfile back in sync with package.json:3 and src-tauri/Cargo.toml:3 so the next cargo build does not warn about a version drift.
- R115 quick win #1: Apache 2.0 SPDX-License-Identifier headers added to source files that were missing them. 100% SPDX coverage on .ts, .tsx, .rs, .svelte now. R114 compliance audit passes on rule 4 (license headers).
- R100 polish already shipped, summarized here for the v0.6.7 chain: low_confidence UI consumer surfaces a "Pulse is not sure" hint when the Smart Engine v3 router returns a low confidence score; tree-sitter Smart Engine ingests AST-level code structure for code-aware recall.
- R114 audit: 8/12 strict hard rules on pulse-desktop, 10/12 targeted with the R115 quick wins #2 and #3 (gradient border + 44dp touch targets). R115 quick wins #2 and #3 live in pulse-desktop, not in the landing repo — the landing is already 12/12 on the audit.
- Build target x86_64-pc-windows-msvc, Tauri 2.11.4, Rust release profile. NSIS 12.27 MB, MSI 16.94 MB, binary 9.98 MB. SHA-256 fingerprints on the download block below.
-
minor v0.6.6 · P1 trio — backup rules, voice input, Settings view
P1 audit (Roman, 2026-08-02) closed: backup rules now exclude app_webview/ from both cloud-backup and device-transfer so the local-first promise holds; voice input via SpeechRecognition is the 8th tool in the NotesView toolbar; the Settings view (Profile, Theme, About, Actions) opens from a gear button in NotesView. R93b-signed APK (v2+v3, no v1) — pre-R95a debug-signed users must uninstall first. Vitest 304/304 (+2 version-assertion tests for APP_VERSION / APP_VERSION_CODE).
- Backup rules (P1 #1): app_webview/ excluded from android:allowBackup and android:fullBackupContent, so Auto Backup to Google Drive and Android device-transfer no longer include the WebView localStorage, IndexedDB, or Capacitor filesystem paths. notes.db and captures.db (the actual user data) still back up as before — only the WebView cache is excluded.
- Voice input (P1 #2): 8th tool in the NotesView M3 toolbar. Tap the mic → webkitSpeechRecognition / Android SpeechRecognizer (Capacitor 8 plugin) starts a stream → text is inserted at the cursor position on final transcript. 3-state visual: idle (outline mic) → listening (red, animated) → finalizing (greyed). Locale auto-detect; falls back to en-US on no-match.
- Settings view (P1 #3): gear button in the NotesView top-right. 4 sections — Profile (display name, app id, version, versionCode), Theme (system / dark / light, currently dark-only), About (Apache 2.0, R93b-signed, link to the changelog), Actions (export notes.db, clear cache, factory reset). No network calls; everything reads from the local store.
- Vitest 302/302 → 304/304 (+2: APP_VERSION 0.6.6 / APP_VERSION_CODE 16 in update-checker.test.ts; gradleReleaseConfig.test.ts pins versionName="0.6.6" / versionCode=16 against the AndroidManifest XML).
- APK 4,607,931 → 1,352,869 B (-3,255,062 B; the migration from a debug-keyed, unminified 4.6 MB bundle to an R93b-signed, R8-shrunk 1.29 MB bundle. R8 obfuscation is on; the JSC bytecode is hermes-compiled; resources.arsc is the only large asset left).
- SHA-256 AD6E33029D3871609774C407597BE49894ECC64B82A53D31C3C066374B45BAB5 (v0.6.6). R93b release.keystore (CN=Pulse Notes, O=Lesside, L=Brest, ST=Brest, C=BY, RSA-2048, valid until 2053-12-17). v1 disabled in R95a; v0.6.6 builds on the same v2+v3 path. Pre-R95a users (debug-signed builds) must uninstall before installing v0.6.6 because the signing key changed.
-
minor v0.6.5 · Manifest chain grown to 7 (bridge for v0.6.3 and v0.6.4)
R93 bridge release: the manifest URL fallback chain in DEFAULT_MANIFEST_URLS grows from 5 to 7 hosts. R92 (yv5eeknt6h6sa) and R90 (ad67rp710vsl7) are added at the head, so v0.6.5+ devices can auto-update forward even if the R88 / R87 hosts go down. v0.6.3 and v0.6.4 users cannot auto-update because their baked-in chain does not include these two hosts — see the side-load page for the manual path. The update checker logic itself is unchanged from R90; this is purely a chain-length bump plus a side-load documentation release.
- DEFAULT_MANIFEST_URLS: 5 → 7 entries. New order: R92 (yv5eeknt6h6sa) → R90 (ad67rp710vsl7) → R88 (32dhrw35m4x2v) → R87 (hrkbksh0x0xz4) → R85 (cq9a31txpromd) → R81 (813khigmhk9k8) → R78 (fy150e36f93n8).
- APP_VERSION 0.6.4 → 0.6.5. APP_VERSION_CODE 14 → 15. package.json and web/package.json bumped to 0.6.5. android/app/build.gradle versionCode 14 → 15, versionName 0.6.5.
- New /release-notes-v0.6.5/ page (M3, 0 emoji, vanilla CSS, DARK) documenting the v0.6.3 / v0.6.4 side-load path with 4-step instructions and full SHA-256 verification.
- 252/252 → 276/276 vitest (+24 for v0.6.5 path: chain head assertions, APP_VERSION bump, compareVersions 0.6.5 vs 0.6.4 and 0.6.10, fetchManifestFromChain walks the chain when R92 host is down, dedup guard, valid HTTPS URL guard, v0.6.5 user sees "no update needed").
- APK 4,556,129 → 4,607,931 B (+51,802 B for the 2 added host strings and the new /release-notes-v0.6.5/ page asset; no code logic delta).
- KNOWN LIMITATION (unchanged from R90): v0.6.3 and v0.6.4 APKs are locked to chains that do not include R92 / R90. v0.6.5 closes the loop for future v0.6.6+ updates; the v0.6.3 / v0.6.4 retro gap is permanent until the v0.1 sync plan ships a stable manifest host.
-
minor v0.6.4 · Manifest URL fallback chain
R90 fix for the chicken-and-egg URL rotation that broke every previous APK after a website_deploy rotation. UpdateChecker now tries a chain of 5 known manifest hosts instead of a single baked-in URL. The most-recent host is tried first; VITE_UPDATE_MANIFEST_URL env override is always at the head. With this chain in place, the next APK that ships after another host rotation will still find a valid manifest. UpdateResult gains a manifestUrl diagnostic field for triage, and the chain grows monotonically (5 → 6 → 7 ...) on each future ship.
- 5-host fallback chain in DEFAULT_MANIFEST_URLS (most-recent first): R90 → R88 → R87 → R85 → R81 → R78.
- Env override VITE_UPDATE_MANIFEST_URL is always placed at index 0 — the head.
- resolveManifestUrls(env) pure helper, getManifestUrls() singleton, fetchManifestFromChain(urls, opts) try-each-URL with attempts[] log.
- UpdateResult gains manifestUrl: string | null for triage — surfaces which host answered.
- markSeen(now: () => number = Date.now) test seam + Math.max(now(), cache.checkedAt + 1) for deterministic forward motion (fixes a pre-existing R88 flake).
- 252/252 vitest (16 new for chain + helper parity; 1 pre-existing markSeen flake fixed in the same patch).
- versionCode 13 → 14. APK 4.34 → 4.35 MB (+408 B from added URLs).
- KNOWN LIMITATION: v0.6.3 APK is locked to the R87 single URL without the chain — see the side-load page for the manual update path.
-
minor v0.6.3 · In-app UpdateChecker revival
R52 shipped an in-app UpdateChecker that polled a remote manifest, surfaced an M3 dialog with force-update support, and verified SHA-256. The implementation was lost in R73 mavis-trash and the R77 greenfield reset. v0.6.3 brings it back. The component ships as update-checker.ts (core) + UpdateCheckerMount.svelte (mount) + UpdateDialog.svelte (M3 dialog). Polls the manifest at 24h TTL, surfaces soft + force modes, verifies SHA-256 against latest_apk_sha256, and opens the release-notes link via @capacitor/browser for a Chrome Custom Tab.
- UpdateChecker core: 27060 B — fetch manifest, parse JSON, compareVersions, in-flight dedup, cache fallback on network error.
- UpdateCheckerMount.svelte (3435 B) — mount point, defends against in-flight collapse, surfaces manifestUrl diagnostic on error.
- UpdateDialog.svelte (9697 B) — M3 dialog, 0 emoji, "Update now" / "Later" actions, SHA-256 fingerprint, release-notes CTA.
- compareVersions gotchas handled: leading "v" stripped, pre-release suffix ("0.6.2-beta") treated equal to "0.6.2", missing segments ("0.6" == "0.6.0"), numeric vs lex (parseInt + default 0, never string compare).
- In-flight dedup by an in-class Promise field — force flag does not skip dedup, it only changes cache-vs-network decision.
- Cache fallback on network error: returns cached manifest with fromCache: true when fetch fails and a cache exists. Only returns manifest: null when there is no cache to fall back to.
- 184/184 → 236/236 vitest (52 new for the chain + helpers + dialog states).
- versionCode 12 → 13. APK 4.34 → 4.34 MB (+1.1 KB from the new components).
-
minor v0.6.2 · Onboarding v2 + 184/184 vitest
Four M3 onboarding screens replace the single splash: Welcome, Capture, Smart Engine, Local-first. No emoji, no celebratory copy, no marketing banner — the user lands in the app, sees the four steps, picks the ones that matter, and gets to the editor in three taps.
- Welcome screen: app name, version, M3 primary button "Get to the editor".
- Capture screen: share-to-Pulse demo, the four ways to land a note (Telegram, Slack, browser, voice).
- Smart Engine screen: one paragraph on what the local router does, the +32 pp / −1370 ms numbers from the v3 evaluation, the threshold 5 toggle.
- Local-first screen: what lives on the device, what does not, and the opt-in E2E sync roadmap for v0.7.
- 184/184 vitest (+34 over v0.6.0): onboarding flow, capture intent, FTS5 search, and the M3 component primitives.
- versionCode 11 → 12. APK +5 KB; the new screens reuse the existing M3 primitives, so the bundle grows almost nothing.
- No web code regressions — 150/150 existing cases still pass; 34 new cases cover the onboarding + capture + search additions.
-
minor v0.6.1 · Adaptive app icon + M3 splash screen
Pulse Notes now launches with a proper Android 8+ adaptive icon (Tokyo Night blue P + 4-point spark) and a Material 3 splash screen that eliminates the white flash on cold start. No code changes, no new features — the app just looks like it belongs on the device.
- Adaptive icon foreground: geometric P (#7aa2f7) with a 4-point spark (#bb9af7) on Tokyo Night background (#1a1b26).
- Monochrome variant for Android 13+ themed icons — the system tints it to match the wallpaper.
- Legacy mipmap PNGs regenerated at mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi (48 to 192 px).
- AppTheme.NoActionBarLaunch now uses Theme.SplashScreen with windowSplashScreenBackground = #1a1b26, so the first frame after process start is dark — no white flash before the WebView loads.
- Center 1400x1400 P+spark on the 2732x2732 splash drawable — fits inside the 1200x1200 safe zone on every screen.
- versionCode 10 → 11. APK grew +12 KB (4.32 → 4.34 MB); the new splash is larger than the old one but the smaller vector icons offset the cost.
- 150/150 vitest still green; no web code changes.
-
major v0.6.0 · Pulse Notes markdown editor on Android
GREENFIELD: built from scratch on Svelte 5 + TS strict + Vite. Not a port. CodeMirror 6 with split-pane, [[wikilink]] backlinks, and tag autocomplete land on Android for the first time.
- GREENFIELD: Svelte 5 + TS strict + Vite + vitest + jsdom — not a port of lost v0.5.x desktop code.
- CodeMirror 6 markdown editor with Lezer highlighting, line numbers, smart indent, keyboard-first.
- Split-pane editor + preview with drag-resize; on mobile, a bottom-sheet toggle (80ms debounce).
- [[wikilink]] backlinks with fuzzy autocomplete + click-to-navigate in preview.
- #tag autocomplete with prefix + subsequence fuzzy match, ranked by usage frequency.
- Material 3 toolbar with 7 formatting actions: bold, italic, code, link, list, h1-h3, image.
- 150/150 vitest tests green across 9 files (markdownIt, notesBacklinks, notesStore, 5 components, NotesView).
- 4.32MB APK, 849KB JS bundle (306KB gzipped), CodeMirror lazy-loaded behind a feature flag.
-
minor v0.5.2 · Split-pane persistence, M3 toolbar polish
Split-pane widths now persist per-note. Toolbar added the image action and Ctrl/Cmd+K link shortcut. Tag autocomplete ranks by frequency, not alphabetical.
- Per-note split-pane width stored in notes table, not localStorage.
- Image action on M3 toolbar with file picker.
- Ctrl/Cmd+K keyboard shortcut for link action.
- Tag autocomplete re-ranked by usage frequency (top tags float).
- 294 unit tests, 0 regressions.
-
minor v0.5.1 · CodeMirror 6 markdown editor ships on desktop
Replaced the plain textarea with CodeMirror 6, markdown-it 14, highlight.js 11, and @lezer/highlight. [[wikilink]] backlinks and split-pane preview land on desktop.
- 5 new components: MarkdownEditor (lazy), MarkdownPreview, NoteToolbar (M3), TagAutocomplete (M3), SplitPane.
- 2 new lib files: markdownIt.ts, notesBacklinks.ts.
- Feature flag notes.markdown.v2 default ON (~82KB gzipped).
- Lezer highlighting for headings, lists, links, code, emphasis.
- Line numbers + current-line gutter, always on.
-
major v0.5.0 · Tier 1 desktop Notes ships
SQLite + FTS5 schema landed on Windows. 8 Tauri commands, 5 React components, tray menu gains a "New note" action. Notes enters beta on Windows.
- SQLite + FTS5 schema with notes, tags, captures, and backlinks tables.
- 8 Tauri commands exposed to the web layer.
- 5 React components for the list, editor, and tag picker surfaces.
- 17 Rust tests, 158 vitest tests, clean release build.
- Tray menu gains a "New note" action.
-
minor v0.4.1 · Notes module scaffolded
The notes/ folder, the capture intent integration, and the first 12 vitest tests for the SQLite adapter.
- notes/ folder structure with adapter, store, and ui subfolders.
- Capture intent integration for share-from-Android flows.
- 12 vitest tests for the SQLite adapter layer.
- No user-facing UI yet — this is the foundation.
-
major v0.4.0 · Notes feature announced
Notes was the headline feature of the v0.4.0 launch. The 12MB installer shipped with the schema and a capture sheet, even though the editor was still a textarea.
- The brief promised a local-first second brain with capture, search, backlinks, and recall.
- All four run through the local Ollama model.
- The 12MB installer shipped with the schema and a capture sheet.
- The editor was still a textarea — that came in v0.5.1.
Try Pulse.
Windows NSIS 12.27 MB · MSI 16.94 MB · Android APK 1.29 MB · no Google Play · no account · no telemetry.