use std::fs; use std::path::PathBuf; use std::sync::Arc; use chrono::{Timelike, Utc}; use chrono_tz::Tz; use dashmap::DashMap; use once_cell::sync::Lazy; use regex::Regex; use tokio::sync::RwLock; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::*; use tower_lsp::{Client, LanguageServer, LspService, Server}; use walkdir::WalkDir; use crate::error::StreamdError; use crate::extract::parse_markdown_file; use crate::localize::{localize_stream_file, merge_repository_configuration, TaskConfiguration}; use crate::models::{LocalizedShard, RepositoryConfiguration}; use crate::timesheet::{ extract_timesheets, find_overlapping_timecards, load_repository_config, BasicTimesheetConfiguration, }; const MD_EXT: &str = "md"; /// R15 file name validation: YYYYMMDD[-HHMMSS][_type][...].md /// The extraction regex requires at least one non-dot char after date/time. static FILE_NAME_REGEX: Lazy = Lazy::new(|| Regex::new(r"^(?P\d{8})(?:-(?P