1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// SPDX-License-Identifier: AGPL-3.0-or-later pub mod claude; pub mod claude_code; pub mod codex; pub mod codex_desktop; mod codex_desktop_event; pub mod copilot_cli; pub mod copilot_vscode; pub mod cursor; pub mod goose; pub mod openclaw; pub mod opencode; pub mod vibe; use std::path::Path; /// Earliest mtime (ms) of `.jsonl` files in `dir`. Returns 0 on failure. pub fn dir_mtime_ms(dir: &Path) -> u64 { std::fs::read_dir(dir) .ok() .into_iter() .flatten() .filter_map(|e| e.ok()) .filter(|e| e.path().extension().map(|x| x == "jsonl").unwrap_or(false)) .filter_map(|e| e.metadata().ok()?.modified().ok()) .map(|t| { t.duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_millis() as u64 }) .min() .unwrap_or(0) } pub fn epoch_ms(t: u64) -> u64 { if t < 1_000_000_000_000 { t.saturating_mul(1000) } else { t } } pub fn value_ts_ms(v: &serde_json::Value) -> Option<u64> { v.as_u64() .map(epoch_ms) .or_else(|| v.as_str().and_then(rfc3339_ms)) } fn rfc3339_ms(s: &str) -> Option<u64> { let dt = time::OffsetDateTime::parse(s, &time::format_description::well_known::Rfc3339).ok()?; u64::try_from(dt.unix_timestamp_nanos() / 1_000_000).ok() }