From 52641f8f3b7d1f4813c6e80105cd80b37656064d Mon Sep 17 00:00:00 2001
From: Yao Jingxi <23722032@bjtu.edu.cn>
Date: Fri, 30 Oct 2026 23:39:04 +0800
Subject: [PATCH 1/6] =?UTF-8?q?fix(core):=20=E6=9C=AC=E5=9C=B0=E5=8E=86?=
=?UTF-8?q?=E5=8F=B2=E6=AF=8F=E4=B8=AA=E9=A1=B9=E7=9B=AE=E9=99=90=E5=88=B6?=
=?UTF-8?q?=20100MB=EF=BC=8C=E5=9F=BA=E7=BA=BF=E8=B7=B3=E8=BF=87=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E7=9B=AE=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 每个项目上限 100MB(按 4KB 分配块计,占用量进程内缓存),其中项目基线最多 50MB
- 基线跳过 node_modules、.venv、target、.claude、.uv-cache 等生成目录和嵌套 Git 仓库
- 保存时清理过期条目和旧版本遗留的排除目录基线;超限按基线→编辑→标签由旧到新淘汰
---
rust/lithe-core/src/project/history.rs | 468 +++++++++++++++++-
.../features/history-snapshots.json | 10 +-
2 files changed, 454 insertions(+), 24 deletions(-)
diff --git a/rust/lithe-core/src/project/history.rs b/rust/lithe-core/src/project/history.rs
index 3e99091b1e..355da55a19 100644
--- a/rust/lithe-core/src/project/history.rs
+++ b/rust/lithe-core/src/project/history.rs
@@ -4,14 +4,63 @@ use crate::project::files::VisibilityRules;
use crate::protocol::{invalid_relative_path, CoreError, ErrorCode};
use crate::protocol::{HistoryEntriesResponse, HistoryEntryResponse};
use serde::{Deserialize, Serialize};
+use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
+use std::sync::{Mutex, OnceLock};
use std::time::{SystemTime, UNIX_EPOCH};
const MAX_FILE_SIZE: usize = 2 * 1024 * 1024;
const MAX_ENTRIES_PER_FILE: usize = 100;
const RETENTION_SECONDS: i64 = 30 * 24 * 60 * 60;
const HISTORY_VERSION: u32 = 2;
+/// Upper bound for one project's history storage, measured in allocated blocks.
+const MAX_STORAGE_BYTES: u64 = 100 * 1024 * 1024;
+/// Baseline snapshots stop here so edits always keep headroom under the cap and
+/// reopening a project does not churn baselines through eviction.
+const MAX_BASELINE_STORAGE_BYTES: u64 = MAX_STORAGE_BYTES / 2;
+/// Small files still occupy whole filesystem blocks; counting blocks keeps the
+/// budget close to what Finder and disk cleaners report.
+const STORAGE_BLOCK_BYTES: u64 = 4096;
+/// Dependency, cache, and build output directories that a baseline never needs.
+///
+/// Like IDEA's excluded roots, these are regenerated by tools rather than
+/// edited, yet a single virtual environment holds tens of thousands of files.
+/// The list repeats the built-in hidden folders so pruning also reclaims
+/// baselines that releases before those rules recorded, and adds tool caches
+/// and agent worktrees that stay visible in the project tree.
+const BASELINE_EXCLUDED_DIRECTORY_NAMES: &[&str] = &[
+ ".artifacts",
+ ".build",
+ ".cache",
+ ".claude",
+ ".git",
+ ".gradle",
+ ".idea",
+ ".mypy_cache",
+ ".next",
+ ".nuxt",
+ ".pytest_cache",
+ ".ruff_cache",
+ ".swiftpm",
+ ".svn",
+ ".tox",
+ ".uv-cache",
+ ".venv",
+ ".worktree",
+ ".worktrees",
+ "DerivedData",
+ "Pods",
+ "__pycache__",
+ "build",
+ "coverage",
+ "design-qa-artifacts",
+ "dist",
+ "node_modules",
+ "out",
+ "target",
+ "venv",
+];
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -110,6 +159,10 @@ pub fn record(request: HistoryRecordRequest) -> Result