diff --git a/src/cli/commands/who.rs b/src/cli/commands/who.rs index a33a0fc..d878820 100644 --- a/src/cli/commands/who.rs +++ b/src/cli/commands/who.rs @@ -54,9 +54,9 @@ fn resolve_mode<'a>(args: &'a WhoArgs) -> Result> { // Disambiguation: if target contains '/', it's a file path. // GitLab usernames never contain '/'. // Root files (no '/') require --path. - if target.contains('/') { + if clean.contains('/') { return Ok(WhoMode::Expert { - path: normalize_repo_path(target), + path: normalize_repo_path(clean), }); } return Ok(WhoMode::Workload { username: clean }); diff --git a/src/core/db.rs b/src/core/db.rs index 5858c7b..0e2feb5 100644 --- a/src/core/db.rs +++ b/src/core/db.rs @@ -140,6 +140,7 @@ pub fn run_migrations(conn: &Connection) -> Result<()> { } Err(e) => { let _ = conn.execute_batch(&format!("ROLLBACK TO {}", savepoint_name)); + let _ = conn.execute_batch(&format!("RELEASE {}", savepoint_name)); return Err(LoreError::MigrationFailed { version, message: e.to_string(), @@ -216,6 +217,7 @@ pub fn run_migrations_from_dir(conn: &Connection, migrations_dir: &Path) -> Resu } Err(e) => { let _ = conn.execute_batch(&format!("ROLLBACK TO {}", savepoint_name)); + let _ = conn.execute_batch(&format!("RELEASE {}", savepoint_name)); return Err(LoreError::MigrationFailed { version, message: e.to_string(), diff --git a/src/core/lock.rs b/src/core/lock.rs index 2e43ed2..056dad6 100644 --- a/src/core/lock.rs +++ b/src/core/lock.rs @@ -135,6 +135,13 @@ impl AppLock { } fn start_heartbeat(&mut self) { + // Stop any existing heartbeat thread before starting a new one + if let Some(handle) = self.heartbeat_handle.take() { + self.released.store(true, Ordering::SeqCst); + let _ = handle.join(); + self.released.store(false, Ordering::SeqCst); + } + let name = self.name.clone(); let owner = self.owner.clone(); let interval = Duration::from_millis(self.heartbeat_interval_ms); diff --git a/src/embedding/chunk_ids.rs b/src/embedding/chunk_ids.rs index e834585..4214b03 100644 --- a/src/embedding/chunk_ids.rs +++ b/src/embedding/chunk_ids.rs @@ -1,6 +1,10 @@ pub const CHUNK_ROWID_MULTIPLIER: i64 = 1000; pub fn encode_rowid(document_id: i64, chunk_index: i64) -> i64 { + assert!( + (0..CHUNK_ROWID_MULTIPLIER).contains(&chunk_index), + "chunk_index {chunk_index} out of range [0, {CHUNK_ROWID_MULTIPLIER})" + ); document_id .checked_mul(CHUNK_ROWID_MULTIPLIER) .and_then(|v| v.checked_add(chunk_index)) diff --git a/src/main.rs b/src/main.rs index e18e5c8..ccd5126 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1217,7 +1217,12 @@ async fn handle_auth_test( eprintln!( "{}", serde_json::to_string(&output).unwrap_or_else(|_| { - format!(r#"{{"error":{{"code":"{}","message":"{}"}}}}"#, e.code(), e) + let msg = e.to_string().replace('\\', "\\\\").replace('"', "\\\""); + format!( + r#"{{"error":{{"code":"{}","message":"{}"}}}}"#, + e.code(), + msg + ) }) ); } else {