Commit Graph
66 Commits
Author SHA1 Message Date
iamdoubz 0b5a85f461 feat(diarization): persist mic_activity.json; reprocess uses the Phase 3 timeline (FR-SPK)
Factor the Phase 3 attribution (you_spans -> mask -> diarize far side -> merge +
name) into a shared phase3_attribute() used by both stop and reprocess. stop now
writes mic_activity.json (the 'You' spans) next to a retained audio.wav
(plaintext timing metadata, local-only, lives/dies with audio.wav); reprocess
prefers that timeline over the voiceprint fallback so re-transcription keeps
correct per-stream 'You'/'Speaker' attribution.
2026-07-14 00:51:41 -05:00
iamdoubz fd9311c482 feat(diarization): Phase 3 stop attribution — mic timeline is 'You', diarize far side masked (FR-SPK)
stop_recording now, when the mic is on, takes 'You' spans straight from the
MicActivity timeline and diarizes the recording with those ranges zeroed, so
sherpa only ever clusters the far side into Speaker N. Merges the span lists and
names them via the existing voiceprint map (You + Speaker 2..). Falls back to
the whole-signal pass + voiceprint match when the mic is off. Adds mask_ranges
helper + tests.
2026-07-14 00:04:58 -05:00
iamdoubz b39352dbff fix(diarization): clear stale speaker rows on reprocess so Participants pane matches (FR-SPK)
Reprocess re-diarizes and upserts the new labels but never deleted the old
ones, so get_meeting (Participants pane) kept returning the discarded run's
labels (e.g. 83) while the transcript showed the new 5. Clear the meeting's
speaker rows before finalize re-inserts the fresh set.
2026-07-13 20:09:03 -05:00
iamdoubz db52b9e812 feat(diarization): live tick re-emits relabeled segments + live 'You' (FR-SPK)
Phase 2 backend. The 15s provisional pass now (1) runs the mic voiceprint
match every tick and merges 'You'/'Speaker N' into the session name map without
overwriting user-set names, and (2) re-emits every committed segment whose
speaker changed via transcript://segment (replace-by-id) so the live transcript
reflects the refined labels instead of a frozen 'S1'.
2026-07-13 19:25:27 -05:00
iamdoubz 25011d0f27 fix(diarization): reprocess re-diarizes + persist mic voiceprint.wav (FR-SPK)
Phase 1. stop_recording writes voiceprint.wav next to a retained audio.wav
(ADR-0009 gated, sealed at rest with the vault); reprocess_transcript now
re-diarizes the fresh transcript and rebuilds the speaker name map from the
voiceprint instead of reusing the stale original-run names, fixing the
collapse to a single 'You' speaker on re-transcription.
2026-07-13 19:19:06 -05:00
iamdoubz dbe845e923 feat(export): 'obsidian' format — one vault note (notes+summary+action items+transcript, no audio) (FR-STORE-4) 2026-07-12 09:32:23 -05:00
iamdoubz 4dff7a58b5 feat(export): portable bundle (meeting.json + summary.json) + import_meeting_bundle (FR-STORE-4) 2026-07-11 22:42:07 -05:00
iamdoubz 70eb182eb4 feat(sync): auto-resync artifacts on edit (notes/summary/transcript/tags/action items) (FR-SYNC-5) 2026-07-11 22:37:51 -05:00
iamdoubz 862ab86860 feat(action-items): cancel reminders for deleted items on confirm 2026-07-11 22:32:15 -05:00
iamdoubz a4b2b9a292 feat(transcription): drive live worker with StreamTuning; store only committed segments 2026-07-11 08:42:25 -05:00
iamdoubz fd556c57a1 feat(import): import_media — file/URL to a transcribed, diarized meeting; auto_record default 2026-07-11 00:38:19 -05:00
iamdoubz 2681a5d8c8 feat(audio): forward mic/system flag on the recording://level event 2026-07-11 00:27:42 -05:00
iamdoubz 45ddc2bd3e feat(commands): live notes commands + calendar range/cleanup commands
Live notes (Granola-style redesign):
- update_live_notes/set_segment_note: live-session-only, mutate
  RecordingSession.manual_notes and write-through to manual_notes.json.
- stop_recording, reprocess_transcript, and resume_transcription now call
  MarkdownNotes::merge (loading manual_notes.json from disk for the
  latter two, which have no live RecordingSession) instead of the old
  transcript-only to_markdown, so re-transcription/crash-recovery never
  silently drops what the user typed.
- refresh_notes_and_notify no longer re-renders/overwrites notes.md on a
  post-finalize speaker rename/merge -- that used to clobber manual
  edits; it still updates the speakers table and emits the live-refresh
  event.

Calendar range/cleanup (14,686-row bloat fix):
- import_pst_core/import_pst take an optional range_days, converted to a
  from timestamp for PstSource.
- New cleanup_calendar_events command wrapping the new store method.
2026-07-11 00:11:45 -05:00
iamdoubz a341afc52f fix(commands): reindex search after generate_summary writes summary.json
summary.json is sealed straight to disk, not through a store write, so
the FTS index needs an explicit nudge to pick up newly generated
summaries (FR-SEARCH-1).
2026-07-10 19:22:04 -05:00
iamdoubz b5f5ef172c feat(commands): auto-label the mic speaker "You" at stop_recording
Wires VoiceSample creation into start_recording (mic-enabled path) and
runs the voiceprint match after the final diarization pass in
stop_recording: on a confident match, persists "You" and "Speaker 2",
"Speaker 3"... via the existing rename_speaker store path, skipping any
label the user already renamed live.
2026-07-10 19:05:28 -05:00
iamdoubz 1cf0be1259 test(commands): cover graph_calendar_enabled in the privacy egress allowlist test (M4.4) 2026-07-07 18:00:20 -05:00
iamdoubz ce4c54c93b style(commands): cargo fmt 2026-07-07 17:57:12 -05:00
iamdoubz d81b4726f9 feat(commands): MS Graph calendar link/import/disconnect + egress allowlist (T8.9, M4.4, FR-CAL-6) 2026-07-07 17:53:13 -05:00
iamdoubz 7490ff5db4 feat(transcription): wire language selection through recording/reprocess/recovery (T8.7, M4.2) 2026-07-07 13:06:00 -05:00
iamdoubz e966181ab8 Merge branch 'worktree-agent-af5a53986b9441608' into feature_chore_bug_005
# Conflicts:
#	src-tauri/src/llm/mod.rs
#	src/lib/views/Settings.svelte
#	src/lib/views/SummaryPanel.svelte
2026-07-07 08:15:04 -05:00
iamdoubz b986c570f7 fix(llm): reset stale hosted endpoint when quick-switching away from Anthropic
apply_llm_provider_args now resets llm_endpoint to Ollama's local
default when switching to a non-Anthropic provider without an explicit
endpoint and the stored endpoint is still Anthropic's fixed hosted
URL. Prevents a future per-use provider switch (SummaryPanel) that
only sends `provider` from silently leaving llm_endpoint pointed at a
third party for a provider that has no business talking to it.
2026-07-07 07:56:09 -05:00
iamdoubz d73af49742 feat(llm): set_llm_provider stores Anthropic key in credential store, extends egress allowlist (T10.2/M3.2)
set_llm_provider now accepts provider "anthropic": the apiKey argument
is written straight to crate::llm::credentials (OS credential store)
and never assigned into Settings, so it structurally cannot reach
settings.json/wa.db (FR-SEC-1). apply_llm_provider_args pulls the
settings-mutation logic into a small pure function specifically so
that guarantee is unit-testable without touching a real keyring.

llm_provider_from_settings gets an "anthropic" arm; api.anthropic.com
joins the settings-derived egress allowlist through the exact same
generic is_local()-based path privacy_self_check_json already uses for
every other provider — no anthropic-specific allowlist code, and the
host only appears once the provider is actually selected (never
unconditionally).

Also fixes pre-existing cargo-fmt drift on one unrelated line this
file's formatter pass touched (CONTENT_RANGE header call).
2026-07-07 07:50:15 -05:00
iamdoubz 2582d8947f Merge branch 'worktree-agent-af937df502b61b006' into feature_chore_bug_005
# Conflicts:
#	src-tauri/src/storage/mod.rs
2026-07-07 01:15:08 -05:00
iamdoubz 63bfc293cb feat(briefs): create/list/get_feature_brief + set_brief_exposed command bodies (T10.6, M1.4/M1.6) 2026-07-07 00:30:04 -05:00
iamdoubz bd97032550 style: rustfmt (incl. one pre-existing long line in serve_recording) 2026-07-07 00:30:00 -05:00
iamdoubz 0ecc72f18f feat(mcp): wire mcp_status/set_mcp_enabled/set_mcp_scope/mcp_access_log (T10.4)
Replaces the four not_implemented() stubs. mcp_status/set_mcp_enabled
reach the process-wide RmcpServer singleton (behind `#[cfg(feature =
"mcp")]`, with a not_implemented fallback for builds without it);
set_mcp_scope/mcp_access_log are plain settings/Store I/O and work in
every build regardless of the `mcp` cargo feature. The token is only
ever returned once, right when set_mcp_enabled mints it -- it is never
re-readable afterwards, same as any other freshly-issued secret.
2026-07-07 00:26:11 -05:00
iamdoubz 999084ab3f feat(mcp): default_settings() covers the new MCP fields (T10.4)
Keeps default_settings() exhaustive now that Settings grew mcp_* fields.
2026-07-07 00:10:37 -05:00
iamdoubz 1634820523 feat(recording): stream + decrypt recordings in memory via waaudio:// (FR-REC-5) 2026-07-06 18:40:12 -05:00
iamdoubz 49893d5874 feat(audio): wire MicBridge so recordings include the user's voice 2026-07-06 18:25:57 -05:00
iamdoubz ea79fb656d docs(commands): correct playback requirement id to FR-REC-5 2026-07-06 17:56:16 -05:00
iamdoubz da25ccaec6 feat: cancel_recording, recording_playback_path, live sync progress 2026-07-06 17:51:57 -05:00
iamdoubz 97b5f67049 feat(audio): wire mic capture + mixer into recording lifecycle (FR-CAP-7) 2026-07-06 16:26:17 -05:00
iamdoubz 2759a0e49a feat(audio): add list_audio_devices command; wire device into start_recording
list_audio_devices runs the (blocking, COM-based) enumeration off the
async runtime via spawn_blocking, same pattern as import_pst_core.
start_recording now passes settings.audio_output_device through to
WasapiCapture::start instead of always capturing the default device.
2026-07-06 16:00:49 -05:00
iamdoubz fb406d62da feat(llm): add generate_tags command
Reuses build_prompt's transcript+metadata assembly (same as
generate_summary) and the same recording-in-progress guard.
2026-07-06 15:38:00 -05:00
iamdoubz 4f80c14f72 feat(meetings): add rename_meeting command
Validates a non-empty trimmed title before delegating to the store.
2026-07-06 15:10:54 -05:00
iamdoubz 871b11d75e refactor(calendar): split import_pst into a reusable core fn
import_pst_core takes &AppHandle/&dyn Store directly instead of the
State<AppState> extractor, so the startup auto-sync pass (lib.rs) can
run the same import logic without going through a Tauri command.
2026-07-06 14:55:34 -05:00
iamdoubz 8f6e8041d6 feat(sync): auto-build Nextcloud/ownCloud DAV path from the server URL
For nextcloud/owncloud, WebDavTarget now derives the canonical
…/remote.php/dav/files/<user>/ path from the entered server URL (origin only, so
a pasted full path normalizes too); other providers use the URL verbatim.
test_sync_target also reuses the stored password when editing an existing
webdav target (unless a new one is typed), so Test works after a URL fix without
re-entering the password. Fixes the confusing 'bare host connects, full URL
fails' behavior (the former was a 404 false-positive, the latter a blank-secret
401).
2026-07-06 11:10:44 -05:00
iamdoubz 224aaf9994 fix(runtime): use gitea /media/ URLs so Git LFS bundles resolve (not the pointer) 2026-07-06 09:45:01 -05:00
iamdoubz e6f19168f8 feat(runtime): download NPU/DirectML runtimes as 7z from the repo raw URLs
extract_7z_flat replaces extract_zip_flat; NPU + DirectML now default to
git.dou.bet raw/branch/main/runtime/{openvino,directml}.7z with pinned SHA-256s
(DirectML no longer requires WA_DIRECTML_RUNTIME_URL). Adds an extraction test
against the real bundle (proves LZMA2+BCJ decode + flatten).
2026-07-06 08:23:49 -05:00
iamdoubz 0317649b48 feat(commands): app_info (version+commit) and open_url for the About page 2026-07-06 07:46:18 -05:00
iamdoubz ceb7e59164 feat(commands): expose directml.applicable in hardware_status (P2) 2026-07-06 07:21:50 -05:00
iamdoubz b69c91a598 feat(commands): route AMD/Intel to DirectML ONNX engine + download_directml_package (P2)
load_transcriber dispatches OnnxOpenVino/OnnxDirectML through one OnnxTranscriber
block. download_and_extract_runtime is parameterized (sha + readiness) so the new
stage_directml_runtime reuses it; hardware_status reports a directml package field.
2026-07-05 19:40:27 -05:00
iamdoubz 7fe0d87e55 feat(transcription): drive engine choice from AccelPath resolver (P0)
load_transcriber now resolves the accel path instead of assuming a GPU
BackendId has a working offload. Only requests whisper GPU offload for
WhisperCuda/WhisperVulkan; NPU goes to the ONNX engine; everything else decodes
on CPU and reports the backend actually used.
2026-07-05 19:27:28 -05:00
iamdoubz 606bf67943 feat(llm): wire llm_advanced through provider construction + defaults (T5.2) 2026-07-04 09:21:27 -05:00
iamdoubz a38bf20e79 feat(npu): download+unzip the hosted OpenVINO runtime bundle w/ progress + sha256 (T3.4) 2026-07-03 09:16:41 -05:00
iamdoubz 1824475cef feat(sync): seal recording on finalize; encrypt-before-upload in pump; honor config flag (T9.12/T8.8) 2026-07-03 08:47:36 -05:00
iamdoubz e194b76f6f feat(vault): vault lifecycle commands; seal summary; decrypt on export (T8.8) 2026-07-03 08:06:05 -05:00
iamdoubz 575118ceba feat(sync): begin_oauth_link command; pump/test dispatch via build_sync_target (T9.9/9.10) 2026-07-03 07:54:29 -05:00
iamdoubz 2969008d8b feat(sync): upload queue pump w/ backoff, sync_meeting/status/retry, finalize hook, sync://job events (T9.5) 2026-07-02 21:56:58 -05:00
iamdoubz e6911a6bff feat(sync): target management + test-connection commands; wire allowlist (T9.3/9.8) 2026-07-02 20:17:03 -05:00