max / goingson
- Co-Authored-By
- Claude Opus 4.6 <noreply@anthropic.com>
41 files changed,
+10 insertions,
-5890 deletions
| @@ -1942,25 +1942,6 @@ | |||
| 1942 | 1942 | "uuid", | |
| 1943 | 1943 | ] | |
| 1944 | 1944 | ||
| 1945 | - | [[package]] | |
| 1946 | - | name = "goingson-mcp" | |
| 1947 | - | version = "0.3.1" | |
| 1948 | - | dependencies = [ | |
| 1949 | - | "chrono", | |
| 1950 | - | "dirs", | |
| 1951 | - | "goingson-core", | |
| 1952 | - | "goingson-db-sqlite", | |
| 1953 | - | "rmcp", | |
| 1954 | - | "schemars 0.8.22", | |
| 1955 | - | "serde", | |
| 1956 | - | "serde_json", | |
| 1957 | - | "sqlx", | |
| 1958 | - | "tokio", | |
| 1959 | - | "tracing", | |
| 1960 | - | "tracing-subscriber", | |
| 1961 | - | "uuid", | |
| 1962 | - | ] | |
| 1963 | - | ||
| 1964 | 1945 | [[package]] | |
| 1965 | 1946 | name = "goingson-plugin-runtime" | |
| 1966 | 1947 | version = "0.3.1" | |
| @@ -3646,12 +3627,6 @@ | |||
| 3646 | 3627 | "subtle", | |
| 3647 | 3628 | ] | |
| 3648 | 3629 | ||
| 3649 | - | [[package]] | |
| 3650 | - | name = "paste" | |
| 3651 | - | version = "1.0.15" | |
| 3652 | - | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3653 | - | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" | |
| 3654 | - | ||
| 3655 | 3630 | [[package]] | |
| 3656 | 3631 | name = "pathdiff" | |
| 3657 | 3632 | version = "0.2.3" | |
| @@ -4525,38 +4500,6 @@ | |||
| 4525 | 4500 | "windows-sys 0.52.0", | |
| 4526 | 4501 | ] | |
| 4527 | 4502 | ||
| 4528 | - | [[package]] | |
| 4529 | - | name = "rmcp" | |
| 4530 | - | version = "0.1.5" | |
| 4531 | - | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 4532 | - | checksum = "33a0110d28bd076f39e14bfd5b0340216dd18effeb5d02b43215944cc3e5c751" | |
| 4533 | - | dependencies = [ | |
| 4534 | - | "base64 0.21.7", | |
| 4535 | - | "chrono", | |
| 4536 | - | "futures", | |
| 4537 | - | "paste", | |
| 4538 | - | "pin-project-lite", | |
| 4539 | - | "rmcp-macros", | |
| 4540 | - | "schemars 0.8.22", | |
| 4541 | - | "serde", | |
| 4542 | - | "serde_json", | |
| 4543 | - | "thiserror 2.0.18", | |
| 4544 | - | "tokio", | |
| 4545 | - | "tokio-util", | |
| 4546 | - | "tracing", | |
| 4547 | - | ] | |
| 4548 | - | ||
| 4549 | - | [[package]] | |
| 4550 | - | name = "rmcp-macros" | |
| 4551 | - | version = "0.1.5" | |
| 4552 | - | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 4553 | - | checksum = "a6e2b2fd7497540489fa2db285edd43b7ed14c49157157438664278da6e42a7a" | |
| 4554 | - | dependencies = [ | |
| 4555 | - | "proc-macro2", | |
| 4556 | - | "quote", | |
| 4557 | - | "syn 2.0.117", | |
| 4558 | - | ] | |
| 4559 | - | ||
| 4560 | 4503 | [[package]] | |
| 4561 | 4504 | name = "rsa" | |
| 4562 | 4505 | version = "0.9.10" |
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | members = [ | |
| 3 | 3 | "crates/core", | |
| 4 | 4 | "crates/db-sqlite", | |
| 5 | - | "crates/goingson-mcp", | |
| 6 | 5 | "crates/plugin-runtime", | |
| 7 | 6 | "src-tauri", | |
| 8 | 7 | ] |
| @@ -47,7 +47,6 @@ | |||
| 47 | 47 | mailparse = { workspace = true } | |
| 48 | 48 | lettre = { workspace = true } | |
| 49 | 49 | ||
| 50 | - | # LLM | |
| 51 | 50 | reqwest = { workspace = true } | |
| 52 | 51 | thiserror = { workspace = true } | |
| 53 | 52 | ||
| @@ -92,7 +91,7 @@ | |||
| 92 | 91 | tauri-plugin-notification = { workspace = true } | |
| 93 | 92 | tauri-plugin-window-state = { workspace = true } | |
| 94 | 93 | tauri-plugin-updater = { workspace = true } | |
| 95 | - | # File watching (for external DB changes from MCP server) | |
| 94 | + | # File watching (for external DB changes) | |
| 96 | 95 | notify = { workspace = true } | |
| 97 | 96 | notify-debouncer-mini = { workspace = true } | |
| 98 | 97 |
| @@ -475,7 +475,6 @@ | |||
| 475 | 475 | <script src="js/components.js"></script> | |
| 476 | 476 | <script src="js/form-modal.js"></script> | |
| 477 | 477 | <script src="js/themes.js"></script> | |
| 478 | - | <script src="js/llm-templates.js"></script> | |
| 479 | 478 | ||
| 480 | 479 | <!-- Utility Managers --> | |
| 481 | 480 | <script src="js/selection-manager.js"></script> |
| @@ -11,13 +11,12 @@ | |||
| 11 | 11 | pub mod export; | |
| 12 | 12 | pub mod external_sync; | |
| 13 | 13 | pub mod jmap; | |
| 14 | - | pub mod llm; | |
| 15 | 14 | pub mod oauth; | |
| 16 | 15 | pub mod state; | |
| 17 | 16 | pub mod sync_scheduler; | |
| 18 | 17 | pub mod sync_service; | |
| 19 | 18 | ||
| 20 | - | // Desktop-only: file watching for external DB changes (MCP server) | |
| 19 | + | // Desktop-only: file watching for external DB changes | |
| 21 | 20 | #[cfg(not(any(target_os = "ios", target_os = "android")))] | |
| 22 | 21 | pub mod db_watcher; | |
| 23 | 22 | ||
| @@ -199,11 +198,6 @@ | |||
| 199 | 198 | commands::get_day_planning, | |
| 200 | 199 | commands::schedule_task, | |
| 201 | 200 | commands::unschedule_task, | |
| 202 | - | commands::get_llm_settings, | |
| 203 | - | commands::save_llm_settings, | |
| 204 | - | commands::test_llm_connection, | |
| 205 | - | commands::evaluate_llm_template, | |
| 206 | - | commands::clear_llm_cache, | |
| 207 | 201 | commands::list_saved_views, | |
| 208 | 202 | commands::list_pinned_views, | |
| 209 | 203 | commands::get_saved_view, |
| @@ -343,7 +343,7 @@ | |||
| 343 | 343 | notifications::start_snooze_watcher(handle, notify_cancel).await; | |
| 344 | 344 | }); | |
| 345 | 345 | ||
| 346 | - | // Start database file watcher for external changes (e.g., from MCP server) | |
| 346 | + | // Start database file watcher for external changes | |
| 347 | 347 | let watcher_handle = app.handle().clone(); | |
| 348 | 348 | db_watcher::start_db_watcher(watcher_handle, db_watcher_shutdown); | |
| 349 | 349 | } | |
| @@ -496,12 +496,6 @@ | |||
| 496 | 496 | commands::get_day_planning, | |
| 497 | 497 | commands::schedule_task, | |
| 498 | 498 | commands::unschedule_task, | |
| 499 | - | // LLM | |
| 500 | - | commands::get_llm_settings, | |
| 501 | - | commands::save_llm_settings, | |
| 502 | - | commands::test_llm_connection, | |
| 503 | - | commands::evaluate_llm_template, | |
| 504 | - | commands::clear_llm_cache, | |
| 505 | 499 | // Saved Views | |
| 506 | 500 | commands::list_saved_views, | |
| 507 | 501 | commands::list_pinned_views, |
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | use goingson_core::{ | |
| 4 | 4 | AttachmentRepository, BackupSettingsRepository, ContactRepository, EmailAccountRepository, | |
| 5 | - | EmailRepository, EventRepository, LlmCacheRepository, LlmSettingsRepository, | |
| 5 | + | EmailRepository, EventRepository, | |
| 6 | 6 | MilestoneRepository, MonthlyReviewRepository, ProjectRepository, SavedViewRepository, | |
| 7 | 7 | SearchRepository, StatsRepository, SyncAccountRepository, TaskRepository, | |
| 8 | 8 | WeeklyReviewRepository, | |
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | use goingson_db_sqlite::{ | |
| 11 | 11 | SqliteAttachmentRepository, SqliteBackupSettingsRepository, SqliteContactRepository, | |
| 12 | 12 | SqliteEmailAccountRepository, SqliteEmailRepository, SqliteEventRepository, | |
| 13 | - | SqliteLlmCacheRepository, SqliteLlmSettingsRepository, SqliteMilestoneRepository, | |
| 13 | + | SqliteMilestoneRepository, | |
| 14 | 14 | SqliteMonthlyReviewRepository, SqliteProjectRepository, SqliteSavedViewRepository, | |
| 15 | 15 | SqliteSearchRepository, SqliteStatsRepository, SqliteSyncAccountRepository, | |
| 16 | 16 | SqliteTaskRepository, SqliteWeeklyReviewRepository, | |
| @@ -39,8 +39,6 @@ | |||
| 39 | 39 | pub attachments: Arc<dyn AttachmentRepository>, | |
| 40 | 40 | pub stats: Arc<dyn StatsRepository>, | |
| 41 | 41 | pub search: Arc<dyn SearchRepository>, | |
| 42 | - | pub llm_settings: Arc<dyn LlmSettingsRepository>, | |
| 43 | - | pub llm_cache: Arc<dyn LlmCacheRepository>, | |
| 44 | 42 | pub milestones: Arc<dyn MilestoneRepository>, | |
| 45 | 43 | pub saved_views: Arc<dyn SavedViewRepository>, | |
| 46 | 44 | pub weekly_reviews: Arc<dyn WeeklyReviewRepository>, | |
| @@ -104,9 +102,6 @@ | |||
| 104 | 102 | // Ensure desktop user exists (single-user mode) | |
| 105 | 103 | ensure_desktop_user_exists(&pool).await?; | |
| 106 | 104 | ||
| 107 | - | // Migrate LLM API key from database to keychain (one-time) | |
| 108 | - | migrate_llm_api_key_to_keychain(&pool).await; | |
| 109 | - | ||
| 110 | 105 | // Create repositories | |
| 111 | 106 | let projects = Arc::new(SqliteProjectRepository::new(pool.clone())); | |
| 112 | 107 | let tasks = Arc::new(SqliteTaskRepository::new(pool.clone())); | |
| @@ -117,8 +112,6 @@ | |||
| 117 | 112 | let attachments = Arc::new(SqliteAttachmentRepository::new(pool.clone())); | |
| 118 | 113 | let stats = Arc::new(SqliteStatsRepository::new(pool.clone())); | |
| 119 | 114 | let search = Arc::new(SqliteSearchRepository::new(pool.clone())); | |
| 120 | - | let llm_settings = Arc::new(SqliteLlmSettingsRepository::new(pool.clone())); | |
| 121 | - | let llm_cache = Arc::new(SqliteLlmCacheRepository::new(pool.clone())); | |
| 122 | 115 | let milestones = Arc::new(SqliteMilestoneRepository::new(pool.clone())); | |
| 123 | 116 | let saved_views = Arc::new(SqliteSavedViewRepository::new(pool.clone())); | |
| 124 | 117 | let weekly_reviews = Arc::new(SqliteWeeklyReviewRepository::new(pool.clone())); | |
| @@ -140,8 +133,6 @@ | |||
| 140 | 133 | attachments, | |
| 141 | 134 | stats, | |
| 142 | 135 | search, | |
| 143 | - | llm_settings, | |
| 144 | - | llm_cache, | |
| 145 | 136 | milestones, | |
| 146 | 137 | saved_views, | |
| 147 | 138 | weekly_reviews, | |
| @@ -255,38 +246,3 @@ | |||
| 255 | 246 | Ok(()) | |
| 256 | 247 | } | |
| 257 | 248 | ||
| 258 | - | /// One-time migration: if LLM API key exists in the database, move it to keychain and set DB column to NULL. | |
| 259 | - | #[instrument(skip(pool))] | |
| 260 | - | async fn migrate_llm_api_key_to_keychain(pool: &SqlitePool) { | |
| 261 | - | let user_id = DESKTOP_USER_ID.to_string(); | |
| 262 | - | ||
| 263 | - | let row: Option<(Option<String>,)> = sqlx::query_as( | |
| 264 | - | "SELECT api_key FROM llm_settings WHERE user_id = ? AND api_key IS NOT NULL AND api_key != ''" | |
| 265 | - | ) | |
| 266 | - | .bind(&user_id) | |
| 267 | - | .fetch_optional(pool) | |
| 268 | - | .await | |
| 269 | - | .unwrap_or(None); | |
| 270 | - | ||
| 271 | - | if let Some((Some(db_key),)) = row { | |
| 272 | - | // Only migrate if keychain doesn't already have a key | |
| 273 | - | if crate::oauth::CredentialStore::get_llm_api_key().is_none() { | |
| 274 | - | match crate::oauth::CredentialStore::store_llm_api_key(&db_key) { | |
| 275 | - | Ok(()) => { | |
| 276 | - | // Clear the key from the database | |
| 277 | - | match sqlx::query("UPDATE llm_settings SET api_key = NULL WHERE user_id = ?") | |
| 278 | - | .bind(&user_id) | |
| 279 | - | .execute(pool) | |
| 280 | - | .await | |
| 281 | - | { | |
| 282 | - | Ok(_) => info!("Migrated LLM API key from database to keychain"), | |
| 283 | - | Err(e) => warn!("Migrated LLM API key to keychain but failed to clear from database: {e}"), | |
| 284 | - | } | |
| 285 | - | } | |
| 286 | - | Err(e) => { | |
| 287 | - | warn!("Failed to migrate LLM API key to keychain: {}", e); | |
| 288 | - | } | |
| 289 | - | } | |
| 290 | - | } | |
| 291 | - | } | |
| 292 | - | } |
| @@ -19,8 +19,8 @@ | |||
| 19 | 19 | }; | |
| 20 | 20 | use crate::error::CoreError; | |
| 21 | 21 | use crate::models::{ | |
| 22 | - | Annotation, Attachment, Email, EmailAccount, EmailAuthType, EmailThread, Event, LlmSettings, | |
| 23 | - | NewAttachment, NewEmail, NewEmailWithTracking, NewEvent, NewLlmSettings, NewProject, | |
| 22 | + | Annotation, Attachment, Email, EmailAccount, EmailAuthType, EmailThread, Event, | |
| 23 | + | NewAttachment, NewEmail, NewEmailWithTracking, NewEvent, NewProject, | |
| 24 | 24 | NewSavedView, NewTask, Project, SavedView, Subtask, Task, TaskFilterQuery, TimeSession, | |
| 25 | 25 | TimeTrackingSummary, UpdateTask, User, | |
| 26 | 26 | }; | |
| @@ -660,44 +660,6 @@ | |||
| 660 | 660 | async fn search(&self, user_id: UserId, query: SearchQuery) -> Result<(Vec<SearchResultItem>, usize)>; | |
| 661 | 661 | } | |
| 662 | 662 | ||
| 663 | - | /// Repository for LLM provider settings. | |
| 664 | - | #[async_trait] | |
| 665 | - | pub trait LlmSettingsRepository: Send + Sync { | |
| 666 | - | /// Gets the LLM settings for a user. | |
| 667 | - | async fn get(&self, user_id: UserId) -> Result<Option<LlmSettings>>; | |
| 668 | - | ||
| 669 | - | /// Creates or updates LLM settings. | |
| 670 | - | async fn upsert(&self, user_id: UserId, settings: NewLlmSettings) -> Result<LlmSettings>; | |
| 671 | - | } | |
| 672 | - | ||
| 673 | - | /// Repository for caching LLM responses. | |
| 674 | - | /// | |
| 675 | - | /// Caches are keyed by prompt hash and optional context date to support | |
| 676 | - | /// date-sensitive queries (e.g., "what's due today?"). | |
| 677 | - | #[async_trait] | |
| 678 | - | pub trait LlmCacheRepository: Send + Sync { | |
| 679 | - | /// Gets a cached response by prompt hash and context date. | |
| 680 | - | async fn get( | |
| 681 | - | &self, | |
| 682 | - | user_id: UserId, | |
| 683 | - | prompt_hash: &str, | |
| 684 | - | context_date: Option<&str>, | |
| 685 | - | ) -> Result<Option<String>>; | |
| 686 | - | ||
| 687 | - | /// Stores a response in the cache. | |
| 688 | - | async fn set( | |
| 689 | - | &self, | |
| 690 | - | user_id: UserId, | |
| 691 | - | prompt_hash: &str, | |
| 692 | - | context_date: Option<&str>, | |
| 693 | - | response: &str, | |
| 694 | - | expires_at: Option<DateTime<Utc>>, | |
| 695 | - | ) -> Result<()>; | |
| 696 | - | ||
| 697 | - | /// Clears all cached responses for a user, returning the count deleted. | |
| 698 | - | async fn clear_all(&self, user_id: UserId) -> Result<u64>; | |
| 699 | - | } | |
| 700 | - | ||
| 701 | 663 | /// Repository for saved view / filter configurations. | |
| 702 | 664 | #[async_trait] | |
| 703 | 665 | pub trait SavedViewRepository: Send + Sync { |