From c4860474364db08b65c97063968f794634a74fe8 Mon Sep 17 00:00:00 2001 From: Jordon Date: Thu, 23 Apr 2026 19:58:31 +0100 Subject: [PATCH 01/25] Update opencode-review.yml --- .github/workflows/opencode-review.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index 6fabd62..b08492b 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -35,6 +35,7 @@ jobs: - Check for code quality issues - Look for potential bugs - Suggest improvements + - If you make any code edits, run 'cd Client && just test' to verify they compile and pass tests before committing. - name: fallback if: ${{ steps.review_primary.outcome == 'failure' }} @@ -51,3 +52,4 @@ jobs: - Check for code quality issues - Look for potential bugs - Suggest improvements + - If you make any code edits, run 'cd Client && just test' to verify they compile and pass tests before committing. From 169aad6c20057cb0415c25ba312ac9df37beb273 Mon Sep 17 00:00:00 2001 From: Jordon Date: Sun, 26 Apr 2026 08:57:34 +0100 Subject: [PATCH 02/25] Fix issues --- Backend/src/tauri_commands/commit.rs | 78 ++++++--------------- Backend/src/tauri_commands/settings.rs | 2 +- Frontend/src/modals/set-upstream.html | 5 +- Frontend/src/styles/modal/repo-settings.css | 12 +++- docs/plugin architecture.md | 5 ++ 5 files changed, 41 insertions(+), 61 deletions(-) diff --git a/Backend/src/tauri_commands/commit.rs b/Backend/src/tauri_commands/commit.rs index 9362439..e200345 100644 --- a/Backend/src/tauri_commands/commit.rs +++ b/Backend/src/tauri_commands/commit.rs @@ -6,10 +6,28 @@ use log::{error, info}; use tauri::{async_runtime, Manager, Runtime, State, Window}; use crate::core::models::VcsEvent; +use crate::repo::Repo; use crate::state::AppState; use super::{current_repo_or_err, progress_bridge, run_repo_task}; +/// Resolves the repository commit identity from Git config. +/// +/// # Parameters +/// - `repo`: Active repository handle. +/// +/// # Returns +/// - `Ok((name, email))` when Git has a configured identity. +/// - `Err(String)` when the repository has no usable commit identity. +fn commit_identity(repo: &Repo) -> Result<(String, String), String> { + repo.inner() + .get_identity() + .map_err(|e| e.to_string())? + .ok_or_else(|| { + "No Git commit identity configured for this repository; set user.name and user.email in Git".to_string() + }) +} + #[tauri::command] /// Commits all staged/working-tree changes using summary + optional description. /// @@ -49,20 +67,7 @@ pub async fn commit_changes( }); info!("Staging changes for commit"); - let (name, email) = repo - .inner() - .get_identity() - .ok() - .flatten() - .or_else(|| { - let n = std::env::var("GIT_AUTHOR_NAME").ok(); - let e = std::env::var("GIT_AUTHOR_EMAIL").ok(); - match (n, e) { - (Some(n), Some(e)) if !n.is_empty() && !e.is_empty() => Some((n, e)), - _ => None, - } - }) - .unwrap_or_else(|| ("OpenVCS".into(), "openvcs@example".into())); + let (name, email) = commit_identity(repo.as_ref())?; info!("Using identity: {} <{}>", name, email); on(VcsEvent::Info { @@ -125,20 +130,7 @@ pub async fn commit_selected( async_runtime::spawn_blocking(move || { let on = progress_bridge(app); - let (name, email) = repo - .inner() - .get_identity() - .ok() - .flatten() - .or_else(|| { - let n = std::env::var("GIT_AUTHOR_NAME").ok(); - let e = std::env::var("GIT_AUTHOR_EMAIL").ok(); - match (n, e) { - (Some(n), Some(e)) if !n.is_empty() && !e.is_empty() => Some((n, e)), - _ => None, - } - }) - .unwrap_or_else(|| ("OpenVCS".into(), "openvcs@example".into())); + let (name, email) = commit_identity(repo.as_ref())?; let paths: Vec = files.into_iter().map(PathBuf::from).collect(); @@ -210,20 +202,7 @@ pub async fn commit_patch( e.to_string() })?; - let (name, email) = repo - .inner() - .get_identity() - .ok() - .flatten() - .or_else(|| { - let n = std::env::var("GIT_AUTHOR_NAME").ok(); - let e = std::env::var("GIT_AUTHOR_EMAIL").ok(); - match (n, e) { - (Some(n), Some(e)) if !n.is_empty() && !e.is_empty() => Some((n, e)), - _ => None, - } - }) - .unwrap_or_else(|| ("OpenVCS".into(), "openvcs@example".into())); + let (name, email) = commit_identity(repo.as_ref())?; on(VcsEvent::Info { msg: "Committing staged hunks…".into(), @@ -293,20 +272,7 @@ pub async fn commit_patch_and_files( })?; } - let (name, email) = repo - .inner() - .get_identity() - .ok() - .flatten() - .or_else(|| { - let n = std::env::var("GIT_AUTHOR_NAME").ok(); - let e = std::env::var("GIT_AUTHOR_EMAIL").ok(); - match (n, e) { - (Some(n), Some(e)) if !n.is_empty() && !e.is_empty() => Some((n, e)), - _ => None, - } - }) - .unwrap_or_else(|| ("OpenVCS".into(), "openvcs@example".into())); + let (name, email) = commit_identity(repo.as_ref())?; on(VcsEvent::Info { msg: "Writing commit…".into(), diff --git a/Backend/src/tauri_commands/settings.rs b/Backend/src/tauri_commands/settings.rs index 40c8263..9935e6e 100644 --- a/Backend/src/tauri_commands/settings.rs +++ b/Backend/src/tauri_commands/settings.rs @@ -110,7 +110,7 @@ pub fn set_global_settings(state: State<'_, AppState>, cfg: AppConfig) -> Result /// - `Ok(RepoConfig)` current effective repository settings. /// - `Err(String)` when repo queries fail. pub async fn get_repo_settings(state: State<'_, AppState>) -> Result { - let mut cfg = state.repo_config(); + let mut cfg = RepoConfig::default(); if let Some(repo) = state.current_repo() { let (identity, remotes) = run_repo_task("get_repo_settings", repo, move |repo| { let identity = match repo.inner().get_identity() { diff --git a/Frontend/src/modals/set-upstream.html b/Frontend/src/modals/set-upstream.html index aaade96..7101318 100644 --- a/Frontend/src/modals/set-upstream.html +++ b/Frontend/src/modals/set-upstream.html @@ -1,10 +1,10 @@ - diff --git a/Frontend/src/styles/modal/repo-settings.css b/Frontend/src/styles/modal/repo-settings.css index cb376d0..6774319 100644 --- a/Frontend/src/styles/modal/repo-settings.css +++ b/Frontend/src/styles/modal/repo-settings.css @@ -8,7 +8,7 @@ border-bottom: 1px solid var(--border); } #repo-settings-modal .dialog.sheet{ - width:30rem; + width: clamp(34rem, 92vw, 44rem); max-width:100%; display:flex; flex-direction:column; @@ -22,6 +22,10 @@ display:grid; gap:1rem; } +#repo-settings-modal .group{ + display:grid; + gap:.45rem; +} #repo-settings-modal .sheet-actions{ background: var(--surface); display:flex; @@ -33,8 +37,14 @@ /* Form controls — theme-aware via tokens */ #repo-settings-modal .panel-form .group label{ color: var(--muted); } +#repo-settings-modal .panel-form .help-text{ + color: var(--muted); + font-size: .875rem; + line-height: 1.35; +} #repo-settings-modal .panel-form input[type="text"], #repo-settings-modal .panel-form input[type="number"], +#repo-settings-modal .panel-form input[type="email"], #repo-settings-modal .panel-form select, #repo-settings-modal .panel-form textarea{ width:100%; diff --git a/docs/plugin architecture.md b/docs/plugin architecture.md index 1585b60..ed1fa2d 100644 --- a/docs/plugin architecture.md +++ b/docs/plugin architecture.md @@ -30,6 +30,11 @@ Core host-to-plugin method groups: - `plugin.*`: lifecycle, menus, and settings hooks - `vcs.*`: backend operations for repository workflows +Repository identity is resolved from Git config, not from an OpenVCS-side cache. +`vcs.get_identity` reads the repository's configured `user.name` and +`user.email`, and commit flows fail when Git has no usable identity instead of +inventing an OpenVCS author. + `plugin.handle_action` requests carry the selected action as `action_id` and an optional `payload` object. Plugin handlers may return a modal definition object to reopen a plugin modal after the action completes. From 91d0e37ed4d92b1c546761b4dc5597c31f4eef09 Mon Sep 17 00:00:00 2001 From: Jordon Date: Sun, 26 Apr 2026 08:57:43 +0100 Subject: [PATCH 03/25] Fix issues --- Backend/src/state.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Backend/src/state.rs b/Backend/src/state.rs index 1755152..cfbcce8 100644 --- a/Backend/src/state.rs +++ b/Backend/src/state.rs @@ -134,14 +134,6 @@ impl AppState { /* -------- repo config -------- */ - /// Returns a snapshot of repository-local settings. - /// - /// # Returns - /// - A cloned [`RepoConfig`] for the current repository context. - pub fn repo_config(&self) -> RepoConfig { - self.repo_config.read().clone() - } - /// Replaces repository-local settings kept in memory. /// /// # Parameters From 8340c7fcf48b6b21f3a20727784496b3985757ac Mon Sep 17 00:00:00 2001 From: Jordon Date: Sun, 26 Apr 2026 08:57:49 +0100 Subject: [PATCH 04/25] Fix issues --- Frontend/src/modals/repo-settings.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Frontend/src/modals/repo-settings.html b/Frontend/src/modals/repo-settings.html index 57a2105..34e1557 100644 --- a/Frontend/src/modals/repo-settings.html +++ b/Frontend/src/modals/repo-settings.html @@ -2,16 +2,19 @@