fix: resolve UTF-8 string slicing bugs and feature flag issues

- Fix silent errors in stdio.rs: clients now receive fallback error
  responses instead of hanging when JSON serialization fails
- Fix UTF-8 panics in keyword.rs: use char-aware slicing instead of
  byte offsets for query sanitization and term highlighting
- Fix UTF-8 panics in prospective_memory.rs: replace hard-coded byte
  offsets with char-aware slicing for natural language parsing
- Fix UTF-8 panics in git.rs: convert byte positions to char positions
  before slicing commit messages
- Fix feature flag bug in vestige-mcp: add proper [features] section
  to forward embeddings and vector-search features from vestige-core,
  enabling the #[cfg(feature = "embeddings")] initialization code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Sam Valladares 2026-01-27 01:14:59 -06:00
parent f10367ecd0
commit bfa91474a6
6 changed files with 70 additions and 44 deletions

View file

@ -540,8 +540,10 @@ impl GitAnalyzer {
// Extract the description (first line, removing the prefix)
let first_line = message.lines().next().unwrap_or("");
let symptom = if let Some(colon_pos) = first_line.find(':') {
first_line[colon_pos + 1..].trim().to_string()
let symptom = if let Some(colon_byte_pos) = first_line.find(':') {
// Convert byte position to char position for safe slicing
let colon_char_pos = first_line[..colon_byte_pos].chars().count();
first_line.chars().skip(colon_char_pos + 1).collect::<String>().trim().to_string()
} else {
first_line.to_string()
};
@ -574,10 +576,13 @@ impl GitAnalyzer {
|| line_lower.contains("closes #")
|| line_lower.contains("resolves #")
{
// Extract issue number
if let Some(hash_pos) = line.find('#') {
let issue_num: String = line[hash_pos + 1..]
// Extract issue number (using char-aware iteration)
if let Some(hash_byte_pos) = line.find('#') {
// Convert byte position to char position for safe slicing
let hash_char_pos = line[..hash_byte_pos].chars().count();
let issue_num: String = line
.chars()
.skip(hash_char_pos + 1)
.take_while(|c| c.is_ascii_digit())
.collect();
if !issue_num.is_empty() {