Commit Graph

16 Commits

Author SHA1 Message Date
Claude
ab3bb9370c fix(viewer): hand off transcript ID only, fetch row from SQLite on mount
HistoryPage previously serialised the full TranscriptDto — text, segments,
manual + LLM tags, audio path — into `localStorage["kon_viewer_item"]` so
the viewer window could pick it up on mount. On a multi-hour transcript
that's MB-scale of user voice content sitting in storage that any
same-origin script in any open Kon window can read.

Hand off only `{ id }` (and a timestamp on re-saves). The viewer fetches
the canonical row from SQLite via the existing `get_transcript` Tauri
command and hydrates via the now-exported `mapTranscriptRow`. Cross-window
sync via the `storage` event still works — the receiving window re-fetches
on event instead of trusting the payload.

- HistoryPage `openViewer` + `openEditor`: write `{ id }` only.
- viewer `onMount` + `handleStorageChange`: route through new
  `loadFromHandoff` which calls `invoke("get_transcript", { id })`.
- viewer `saveItemToHistory`: re-stamp localStorage with `{ id, stamp }`
  to retrigger the storage event in sibling windows without leaking
  content.
- `mapTranscriptRow` exported from page.svelte.ts for the viewer's use.

Backward-compatible at the parse layer: the `{ id }` shape extracts cleanly
from a stale full-DTO payload (TranscriptEntry already carries `id` at top
level), so a session that survives the upgrade picks up the new path on
next handoff without manual cleanup.

https://claude.ai/code/session_0189xUb6ie6t9qHkzatGZ9Rb
2026-04-25 08:47:12 +00:00
Claude
dfa6457f1f fix(history): bulk delete + clear-all now persist to SQLite
The Phase 9 bulk-delete path passed UUID strings to deleteFromHistory(index),
which expected an integer; JS coerced the string to NaN and splice(NaN, 1)
collapsed to splice(0, 1), so bulk-delete silently removed the first N visible
rows instead of the selected ones, then fired delete_transcript against the
wrong IDs.

Clear-all called saveHistory(), which was a no-op stub left over from the
same incomplete-refactor pattern that produced the manualTags persistence bug
fixed in 7eb52d9. The in-memory array was emptied, but SQLite still held
every transcript, so they reappeared on next loadHistory().

- Add deleteFromHistoryById(id) next to the index-keyed deleteFromHistory.
- bulkDelete now calls deleteFromHistoryById.
- clearAll now awaits an explicit per-id delete loop and surfaces a toast on
  partial failure.
- Remove the saveHistory() stub and its sole caller's import.

https://claude.ai/code/session_0189xUb6ie6t9qHkzatGZ9Rb
2026-04-25 06:54:01 +00:00
7fc971df05 feat(phase9): History LLM tag UI — per-row Tag, chips, promote, batch
Per-row Tag button calls extract_content_tags_cmd, persists via
saveTranscriptMeta. Dashed-italic chips render the AI tags distinct
from manual; clicking a chip promotes it into manualTags (the
LLM tag disappears, the manual one stays). Top toolbar gains "Tag all
untagged" for batch tagging across the corpus, with progress text.
Existing addManualTag / removeManualTag handlers swap their no-op
saveHistory() calls for saveTranscriptMeta — picks up the latent
manualTags persistence bug as a side effect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 00:13:55 +01:00
c26d82c26a feat(phase9): History bulk select + bulk export
Slim leading checkbox on every row, tinted-row state when selected.
Bulk-action toolbar appears only when selection is non-empty: select
all (visible), clear, export selected (via exportTranscriptsToDir),
delete selected (single confirm). Esc clears selection. Cmd/Ctrl+A
selects all visible when focus is inside the list and not in a text
input. Stop-propagation on the checkbox keeps the click off the
row-expand toggle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:51:27 +01:00
eb6e291191 feat(phase9): HistoryPage .md export via save dialog
Replaces the clipboard-only path with saveTranscriptAsMarkdown. User
picks the location via the OS save dialog; cancellation leaves no side
effect, no toast, no fallback. Toast on success names the file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:49:58 +01:00
d6bf9ed245 refactor(frontend): migrate JS modules to TypeScript
Wholesale JS -> TS migration of the frontend — stores, utils, actions,
and all Svelte component scripts adopt type annotations. Compile-time
surfaces (app.d.ts, lib/types/) added for shared DTO types.

Build plumbing:
  - package.json: dev:frontend script that runs svelte-kit sync first
  - tauri.conf.json: beforeDevCommand points at dev:frontend
  - run.sh: dropped the sed-hack that temporarily blanked beforeDevCommand;
    now relies on npm run dev:frontend to avoid double-Vite
  - jsconfig.json: allowImportingTsExtensions

Preserves all Group 1 behaviour:
  - page.svelte.ts keeps loadHistory / loadTasks Tauri-first, no
    localStorage; saveTranscriptMeta + mapTranscriptRow + mapTaskRow
    intact; update_task_cmd and update_transcript_meta_cmd invocations
    carry the correct payload shape.
  - Toasts, preferences stores typed without behaviour change.
  - Viewer still routes segment edits through saveTranscriptMeta; the
    Task 1.5 TODO markers are gone.

taskExtractor.ts is functionally improved during the migration:
  - multi-task matches in the same sentence
  - list-style shopping-verb expansion (get bread, milk, and cheese)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:05:54 +01:00
ea48d03cee agent: dogfood polish 2026/04/19 — Linux native chrome + History redesign + mic picker cleanup
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
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>
2026-04-19 14:30:42 +01:00
b479a368e7 fix(clipboard): use navigator.clipboard.writeText as primary, arboard as fallback — fixes silent failure on Linux/XWayland 2026-04-19 10:21:10 +01:00
0e22ec591d ui: Day 4 frontend — dual-write history to SQLite + persist History rename
addToHistory, renameHistoryEntry, deleteFromHistory in
src/lib/stores/page.svelte.js now dual-write to:
- the in-memory `history` array (UI snappiness, unchanged)
- localStorage (offline / browser-preview fallback, unchanged)
- SQLite via the new Tauri commands from 1cce567 (the canonical store)

The SQLite write is best-effort: failure does not lose the in-memory
copy. Console-warns for diagnostic visibility. Browser-preview path
correctly skips the Tauri call.

HistoryPage rename flow (renameItem) now calls renameHistoryEntry, which
goes through update_transcript. Closes the long-standing TODO from
architecture-review.md §13: rename was UI-only, never persisted, lost
on reload.

On rename failure a warn-toast surfaces "your change is visible now but
did not save" so the user is not surprised on next launch.

NOT WIRED YET (deferred):
- HistoryPage.searchQuery still filters in-memory rather than calling
  search_transcripts. Fine for small histories; FTS5 infrastructure is
  in place to upgrade when needed.
- Reading initial history from SQLite on session boot. localStorage
  remains the cold-start source for now; SQLite catches up via dual-
  write. A backfill / one-time sync command can land later.
2026-04-17 13:12:38 +01:00
jake
5caf886252 agent: history — restyle with brand tokens and empty state
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:04:06 +00:00
jake
4c0fd0aeda agent: foundation — sync incremental changes from legacy codebase
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:50:32 +00:00
jake
4d962adea6 refactor(kon): history page — compact list view with expand-to-detail
- Replace card-per-entry layout with single-line rows (title truncated, duration, source icon, date, chevron)
- Add expand/collapse per row via expandedId $state (id-based, one at a time)
- Expanded detail shows full transcript, audio player (when active), and action buttons (Rename, Copy, Open viewer, Delete)
- All existing functionality preserved: search, playback, rename, delete, openViewer, clearAll

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:28:41 +00:00
jake
8b34fed606 refactor(kon): add design tokens — radius scale, title size, button component classes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:17:25 +00:00
jake
c463293935 fix(kon): security audit fixes — CSP, XSS, unwraps, key rename
Security fixes from code audit:
- CSP re-enabled in tauri.conf.json with strict directives
  (was null — critical vulnerability)
- XSS fix in viewer highlightText(): HTML entities escaped before
  inserting <mark> tags via {@html}
- Removed 3 unwrap() calls in rule_based.rs British English conversion
  — replaced with safe let-else guards
- Removed unwrap() on main window lookup in lib.rs setup — now uses
  if-let for graceful handling
- Wrapped JSON.parse in DictationPage transcription-result listener
  with try/catch

Rebrand cleanup:
- Renamed all localStorage keys from ramble_* to kon_* across
  7 files (stores, viewer, float, history)

12 tests passing, clippy clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:51:47 +00:00
jake
0bbdbc0591 feat(kon): replace browser clipboard with arboard
- New copy_to_clipboard Tauri command using arboard 3.6
- Replaced all 5 navigator.clipboard.writeText() calls across
  DictationPage, HistoryPage, FilesPage, and viewer with invoke()
- Native clipboard access independent of WebView permissions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:48:19 +00:00
jake
9926a42b7a feat(kon): scaffold hybrid modular workspace
- Cargo workspace with 6 domain crates: core, audio, transcription, ai-formatting, storage, cloud-providers
- Minimal Tauri shell (lib.rs + main.rs) with plugin registration
- Svelte 5 frontend copied from Ramble v0.2
- All crates compile as empty stubs
- App identifier: uk.co.corbel.kon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:21:38 +00:00