feat(session): #137 prune stale workspace snapshots at session boot
`run_interactive` now calls `session_manager::prune_workspace_snapshots_at_boot` right after the system-skills installer, dropping any snapshot in the side-git repo older than 7 days (default; configurable via the new `[snapshots]` section in `config.example.toml`). The helper is non-fatal: a missing `git` binary, read-only home, or absent snapshot dir all log a single WARN (or DEBUG for the count of pruned commits) and return, so the TUI keeps starting even when retention can't run. Also document the snapshot subsystem in `config.example.toml` — disk-footprint expectations, where the side repo lives, and how `/restore` / `revert_turn` consume it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -213,6 +213,27 @@ default_text_model = "deepseek-ai/deepseek-v4-pro"
|
||||
# threshold_secs = 30
|
||||
# include_summary = false
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────────
|
||||
# Workspace Snapshots (#137)
|
||||
# ─────────────────────────────────────────────────────────────────────────────────
|
||||
# Each turn the TUI takes a `pre-turn:<seq>` and `post-turn:<seq>` snapshot of
|
||||
# your workspace into a side-git repo at:
|
||||
#
|
||||
# ~/.deepseek/snapshots/<project_hash>/<worktree_hash>/.git
|
||||
#
|
||||
# Your own `.git` is never touched — `--git-dir` and `--work-tree` are always
|
||||
# set together when shelling out to git. Use `/restore N` (slash command) or
|
||||
# the `revert_turn` tool to roll the working tree back. Conversation history
|
||||
# is unaffected.
|
||||
#
|
||||
# Disk footprint: ~1-2 GB worst case for a 100 MB workspace × 12 turns/day,
|
||||
# typically far less thanks to git's content-addressed storage. The session
|
||||
# boot prunes anything older than `max_age_days` (default 7).
|
||||
#
|
||||
# [snapshots]
|
||||
# enabled = true # Snapshot workspace pre/post each turn for /restore
|
||||
# max_age_days = 7 # Older snapshots pruned at session start
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────────
|
||||
# Hooks (optional)
|
||||
# ─────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -2788,6 +2788,11 @@ async fn run_interactive(
|
||||
logging::warn(format!("Failed to install system skills: {e}"));
|
||||
}
|
||||
|
||||
// Prune stale workspace snapshots from prior sessions (7-day default).
|
||||
// Non-fatal: a flaky disk, missing `git`, or read-only home should
|
||||
// never block the TUI from starting.
|
||||
session_manager::prune_workspace_snapshots_at_boot(&workspace);
|
||||
|
||||
tui::run_tui(
|
||||
config,
|
||||
tui::TuiOptions {
|
||||
|
||||
@@ -370,6 +370,32 @@ pub fn default_sessions_dir() -> std::io::Result<PathBuf> {
|
||||
Ok(home.join(".deepseek").join("sessions"))
|
||||
}
|
||||
|
||||
/// Boot-time hook: prune workspace snapshots older than the configured
|
||||
/// retention window for `workspace`. Failure is logged but never fatal —
|
||||
/// the session boot must not block on a flaky disk or missing `git`.
|
||||
///
|
||||
/// Called once per `run_interactive` invocation. The default retention
|
||||
/// (7 days) is governed by `crate::snapshot::DEFAULT_MAX_AGE`.
|
||||
pub fn prune_workspace_snapshots_at_boot(workspace: &Path) {
|
||||
prune_workspace_snapshots(workspace, crate::snapshot::DEFAULT_MAX_AGE);
|
||||
}
|
||||
|
||||
/// Prune snapshots older than `max_age` for `workspace`.
|
||||
///
|
||||
/// Always non-fatal. Returns silently — callers don't need the count
|
||||
/// (the underlying repo logs at WARN if anything blew up).
|
||||
pub fn prune_workspace_snapshots(workspace: &Path, max_age: std::time::Duration) {
|
||||
match crate::snapshot::prune_older_than(workspace, max_age) {
|
||||
Ok(0) => {}
|
||||
Ok(n) => {
|
||||
tracing::debug!(target: "snapshot", "boot prune removed {n} snapshot(s)");
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(target: "snapshot", "boot prune failed: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `SavedSession` from conversation state
|
||||
pub fn create_saved_session(
|
||||
messages: &[Message],
|
||||
|
||||
Reference in New Issue
Block a user