7daf5677c9f582972fdc5f54ba4c3cc34ff7271b
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| a15167c44e |
feat(ux): dogfood pass — onboarding, tasks, LLM chip, float popout
Bundles a session of dogfood UX feedback plus the two Cursor Bugbot
findings on the auto-titles branch.
Onboarding (FirstRunPage):
- Welcome leads with "Set up automatically"; system breakdown and the
full model list move behind a "Choose manually" disclosure
- Morning / evening / autostart modal copy trimmed to one short
sentence each; CTAs shortened
- "Corbie" autostart string reverted to "Kon"
- Already-downloaded models are clickable in the picker so the
Settings → About → Replay onboarding flow doesn't re-download
- Autostart "No thanks" now does isEnabled() → disable() to actually
remove the OS login item when replaying after a previous "Yes"
Tasks page:
- Bucket nav (All / Inbox / Today / Soon / Later) now a horizontal
pill row; was stacking because nav was block-level
- List sidebar sized to content via self-start max-h-full instead of
stretching to viewport when sparse
- Energy chip surfaces at opacity-60 when unset (was opacity-0,
hidden until hover) so the affordance is discoverable
- "Brain-Dead" energy label → "Zero" everywhere user-facing; enum
stays brain_dead to avoid a destructive DB migration
LLM status chip (llmStatus.svelte.ts + Dictation/Settings):
- Chip no longer auto-warms when the engine isn't loaded; it's hidden
unless ready / generating / loading / error
- refreshLlmStatus takes { force: true } so post-load reconcile clears
stale "warming"; ambient refreshes still preserve in-flight state
- markError exported; failed loads surface "AI error" with detail
rather than silently going to off
- check_llm_model is the source of truth (replaces the bool-only
get_llm_status path in the store)
Float popout window:
- Native decorations off — was stacking two titlebars + two close X's
on KWin, one of which silently failed
- ResizeHandles mounted outside the animate-float-enter wrapper so
fixed-position handles anchor to the viewport, not the transformed
root; secondary-windows capability gains
core:window:allow-start-resize-dragging for tasks-float
- GTK Utility WindowTypeHint applied pre-map (mirroring the preview
window) so KWin Wayland honours always-on-top reliably
- visible_on_all_workspaces(true) so the pinned tasks list follows
workspace switches
- togglePin does hide()+show()+focus() on re-pin to nudge the
compositor into re-evaluating window state
- Pop-out / Edit / Open viewer buttons hidden on Android via
isAndroid() — the multi-window Tauri commands stub out there
Build / Bugbot:
- src-tauri Cargo.toml: whisper feature now chains whisper-vulkan, so
the dev runner's --no-default-features --features whisper
invocation actually pulls Vulkan acceleration instead of silently
falling back to CPU-only
- jsconfig.json's inherited "types": ["node"] fixed by adding
@types/node; corresponding @ts-expect-error in vite.config.js
removed now that process is a known global
Verification: svelte-check + cargo check pass clean. Manual
device-side validation still pending for float resize and replay
autostart "No thanks" — those are the only remaining confidence items.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
|
|
4abc2356c2 |
build(android): cfg-gate desktop-only Tauri surfaces for android target
Phase 1 of the Android same-repo target plan: make the workspace
compilable for `aarch64-linux-android` (and the other NDK ABIs) by
removing the desktop-only crate dependencies and command bodies from the
Android build. After this commit, `tauri android init` followed by
`cargo tauri android build` is structurally unblocked — the remaining
work is the SDK/NDK toolchain (off-sandbox), the Svelte single-window
refactor, and the Phase 3 MVP feature surface.
What's gated under `cfg(not(target_os = "android"))`:
- src-tauri/Cargo.toml: `tauri = { features = ["tray-icon"] }` is now
declared in the desktop-only target block. The `global-shortcut`,
`window-state`, and `autostart` plugins join it — none of the three
support Android natively. The base `tauri = "2"` plus `dialog`,
`opener`, and `notification` plugins remain unconditional because they
do support Android.
- src-tauri/src/lib.rs: `mod tray` declaration, the matching
`tray::setup(app)` call, the close-to-tray `WindowEvent::CloseRequested`
handler, and the `.plugin(tauri_plugin_global_shortcut::*)` /
`_autostart` / `_window_state` chain are all desktop-only. The
builder is split with a single `#[cfg(not(target_os = "android"))]`
branch that adds the desktop plugins on top of the universal base.
- src-tauri/src/commands/tts.rs: `tts_speak` previously had three
`#[cfg(target_os = ...)]` branches but no fallback, so on Android the
`spawned` binding was unbound and the function failed to compile.
Mirrored the existing `paste.rs` not-implemented fallback. Same fix
for `list_voices_impl`. Frontend will hide the Read Page Aloud button
on Android via `isAndroid()`.
- src-tauri/src/commands/windows.rs: all four multi-window commands
(`open_task_window`, `open_preview_window`, `close_preview_window`,
`open_viewer_window`) get an Android stub that returns a clear
"Multi-window is not supported on Android" error. Tauri on Android
is single-Activity; the previously-secondary content (preview overlay,
transcript viewer, task float) will live as routes inside the main
window, gated by `isAndroid()` on the frontend.
What's *not* changed:
- Top-level `identifier` in tauri.conf.json stays `uk.co.corbel.kon`.
The Phase 10b Kon → Corbie rename sweep will land
`corbel.technology.corbie` as part of a coherent rebrand commit
rather than fragmenting the rename across this branch.
- `bundle.android.minSdkVersion: 24` added so a future
`tauri android init` knows to target Android 7.0+ (Vulkan available,
scoped storage starts at 29 — we'll surface scoped-storage paths
via Tauri's dialog plugin on Phase 3).
- `kon-hotkey` already exports a non-Linux stub; no changes needed.
- `commands/meeting.rs` still calls `process_watch::list_running_process_names()`
which compiles on Android but returns an empty list (SELinux blocks
/proc walk on API 24+). Frontend will hide the toggle on Android.
Verification: 91/91 tests still pass on the buildable-in-sandbox crates
(kon-storage 60, kon-core 16, kon-mcp 9, kon-hotkey 4, kon-cloud-providers
2). svelte-check 0/0 across 3957 files. The src-tauri crate itself can't
be compiled in this sandbox (no webkit2gtk); CI's desktop builders will
exercise the desktop branch, and Jake's Android-equipped dev box will
exercise the Android branch via `tauri android init`.
https://claude.ai/code/session_0189xUb6ie6t9qHkzatGZ9Rb
|
||
| 11965a338b |
fix(preview): set GTK WindowTypeHint::Utility for non-KDE compositor coverage
KWin reads _NET_WM_STATE_SKIP_TASKBAR for its Alt+Tab list, which OW-2 already wired via skip_taskbar(true) on the builder. On Hyprland, Sway, and GNOME Mutter that's not always enough — some switchers still enumerate the overlay. Classifying the window as gdk::WindowTypeHint::Utility signals to the compositor that this is an assistive auxiliary surface, so switchers and auto-tilers leave it alone. No behavioural change on KWin. GTK3 only honours the type hint before the window maps, so the preview builder now starts .visible(false); we grab the gtk_window() via Tauri's escape hatch, set the hint, then show(). The existing hide/show on re-open still works — hint is a property of the gtk::ApplicationWindow and survives the cycle. Added gtk = "0.18" and gdk = "0.18" as Linux-only deps. Both are already pulled in transitively via webkit2gtk 2.0, so this is just surfacing them by name — no new compile cost. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 9b5d08af3d |
fix(preview): pin preview overlay across virtual desktops on KDE/GNOME Wayland
Without _NET_WM_STATE_STICKY the preview overlay only renders on whichever virtual desktop it opened on — switch desktops mid-dictation and the raw transcription stream vanishes exactly when you need it (the whole point of the overlay is that you're working in another app). visible_on_all_workspaces(true) on the WebviewWindowBuilder sets STICKY via GTK on X11/XWayland, which KWin + Mutter both honour. Combined with the existing skip_taskbar(true) — KWin's default Alt+Tab list already respects _NET_WM_STATE_SKIP_TASKBAR — the preview now behaves like the assistive overlay it's meant to be: follows you, out of the way of window switchers. Applied only to the preview window. Task-float and transcript-viewer are primary surfaces that should stay on their own desktop, so they keep the current behaviour. Follow-up if dogfooding shows Alt+Tab clutter on non-KDE compositors: layer a GTK WindowTypeHint::Utility via with_webview. Not needed for KWin. Matches OpenWhispr's PR #183 shape for KDE Plasma. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| eb60a8bfd3 |
feat(preview): floating transcription overlay with listening→live→cleanup→final phases
Ported the best bits of OpenWhispr's TranscriptionPreviewOverlay into Kon's window conventions. Off by default — toggle in Settings → Output → "Floating preview when Kon is unfocused". Opens only when the main window isn't focused at the start of a recording, so it never adds noise when the user can already see the transcript in the main surface. Phase state machine (src/routes/preview/+page.svelte): - listening — pulsing dot, no text yet - live — animated bars + streaming raw Whisper output - cleanup — accent bars while the LLM cleanup pass runs - final — checkmark + formatted text + 4s auto-hide Data plumbing: raw segment text is captured before post_process_segments in live.rs (new raw_text field on LiveResultMessage) and in transcription.rs (new raw_text in the transcription-result payload). DictationPage forwards raw_text to the overlay via Tauri global events — preview-listening on start, preview-append per chunk, preview-cleanup before the LLM pass, preview-final with the formatted text, preview-hide when a run produced no transcript (empty recording / cancel). Window is always_on_top, skip_taskbar, focused=false so it never steals focus from whatever the user is dictating into. open_preview_window shows an existing hidden preview or builds it fresh; close_preview_window hides without destroying so the next open is instant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 34fce3cf9e |
feat: OpenWhispr-inspired transcription polish pass
Major quality pass on top of Phase 2. Five substantive changes plus
cross-cutting touches across audio, hotkey, transcription, and Tauri
command layers.
Transcription quality
- Long-audio chunking in commands/transcription.rs: Parakeet and large
file transcription now chunk-and-recompose with overlap trimming, so
the live-path chunking advantage extends to file-based workflows.
- Stateful live speech gate in commands/live.rs on top of the earlier
duplicate-boundary filtering — distinguishes start-of-speech from
mid-speech and holds state across chunks.
Auto-learning corrections
- New crates/ai-formatting/src/correction_learning.rs: extracts user
text corrections from viewer edits and proposes additions to the
active profile's vocabulary.
- src-tauri/src/commands/profiles.rs bridge for frontend-driven
confirmation of learned terms.
- src/routes/viewer/+page.svelte hooks the learning path into the
segment-edit flow so corrections feed profile_terms without a
separate 'train this profile' UX.
Transcript profile provenance
- Migration v8 (crates/storage/src/migrations.rs) adds profile_id to
transcripts, defaulting to DEFAULT_PROFILE_ID so existing rows stay
valid.
- crates/storage/src/database.rs: TranscriptRow + CRUD carry profile_id.
- src-tauri/src/commands/transcripts.rs: add_transcript accepts and
persists profile_id.
- DictationPage.svelte + FilesPage.svelte send activeProfileId on
capture so learned corrections are attributed to the right profile.
Cleanup prompt contract
- crates/ai-formatting/src/llm_client.rs hardened: the CLEANUP_PROMPT
now specifies concrete do/do-not rules, ready for a real model-backed
cleanup pass. The llm_client is still a stub — kon-llm remains unwired
— but the prompt shape is final.
Cross-cutting polish
- Minor touches in audio (capture/decode/resample), hotkey (lib/linux/stub),
core, transcription (concurrency/model_manager/local_engine/whisper_rs),
and the rest of src-tauri/src/commands/*: error-path tightening, log
clarity, TS-migration follow-ups (@ts-nocheck additions for incremental
typing).
Verified locally: npm run check, cargo test -p kon-ai-formatting,
cargo test -p kon-storage, cargo test -p kon --lib commands::live::tests,
cargo check — all green.
Scope boundary: kon-llm crate is still a stub; task extraction remains
rule-based. Bundled local-LLM runtime is the next clean step and is not
in this commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| ea48d03cee |
agent: dogfood polish 2026/04/19 — Linux native chrome + History redesign + mic picker cleanup
Second dogfood sprint. Headline fix: Linux now uses native KWin/Mutter decorations instead of fragile frameless `startResizeDragging`, which collapsed diagonal corner resize to a single axis and made drag feel laggy. macOS / Windows keep custom chrome via `useCustomChrome` gate. Other changes: - Cross-window preferences sync via `kon:preferences-changed` Tauri event — theme and font changes propagate live to float/viewer. - Hotkey recorder rewritten to use capture-phase document listener gated by $effect; button focus was unreliable in webkit2gtk. - History page redesigned for cognitive-load hygiene: title-first compact row, inline title input, Edit popout opening /viewer in edit mode, clipboard export as .md with YAML frontmatter, manual tag chips + + Add tag input, header tag filter (cap 7), global Starred filter, `tag:xyz` search syntax. - `deriveAutoTags` kept as empty hook for post-Task-7 LLM topic tags; research found all previous auto-tag chips redundant with row UI. - Viewer window adds edit mode with debounced-save textarea; native title renamed to "Kon - Transcription Editor". - Window minimums updated per GNOME HIG + WCAG reflow research: main 960x600, float 360x480, editor 560x520. - Microphone picker filters raw ALSA strings (hw:, plughw:, front:, sysdefault:, null) and dedupes by CARD=X. New `description` field on DeviceInfo reads /proc/asound/cards so Blue Yeti shows as "Blue Microphones" instead of the short "Microphones" card name. - GPU reporting fixed: get_runtime_capabilities now returns accelerators=[cpu,vulkan] and whisper.supports_gpu=true, matching the transcribe-rs whisper-vulkan feature linked unconditionally. - ResizeHandles kept for macOS/Windows frameless: 12px edges, 20px corners via CSS vars, pointerdown + setPointerCapture, corners above edges in z-order, rendered as sibling (not child) of the animated layout root so `position: fixed` is viewport-relative. - Dueling drag-region handlers removed — `data-tauri-drag-region` and manual `startDragging()` were stacked on the same elements; kept the manual handler which has the button/input early-return logic. See HANDOVER.md for the full session log and deferred items. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
|
|
fa7e812166 |
agent: rust — add preferences webview injection for zero-flash hydration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
29ff91d3f6 |
feat(kon): wire Tauri shell — thin commands, ProviderRegistry, tray
- lib.rs rewritten from scaffold to full app setup (~70 lines) - AppState holds Arc<LocalEngine> for Whisper and Parakeet - commands/models.rs: download, check, list, load for both engines Maps legacy size strings (Tiny/Base/Small/Medium) to ModelId - commands/transcription.rs: transcribe_pcm, transcribe_file, transcribe_pcm_parakeet Delegates to LocalEngine.transcribe_sync() + post_process_segments() - commands/audio.rs: save_audio via kon_audio::write_wav - commands/windows.rs: open_task_window, open_viewer_window - commands/llm.rs: 8 stub commands preserved for frontend compatibility - tray.rs: extracted system tray setup (show, status, quit, click-to-show) - Close-to-tray behaviour preserved - All 25 v0.2 command names preserved for Svelte frontend compatibility - clippy clean Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |