Skip to main content

Module scratchpad

Module scratchpad 

Source
Expand description

Per-session scratch directories.

Each chat session gets a private on-disk scratch area keyed by its conversation id: <system-temp>/mermaid-<uid>/<project-slug>/<session-id>/scratchpad. Tools and spawned subprocesses use it for intermediate files instead of the shared system temp dir. Living under the system temp dir means tmpfs speed where the OS provides it and a free wipe on reboot; the mermaid-<uid> root and each session dir are tightened to 0700 so other local users can neither read nor pre-create paths inside them.

Lifecycle: the reducer emits Cmd::EnsureScratchpad at startup and whenever the conversation id changes (/clear, /load, rewind fork); the effect layer materializes the directory here and reports it back via Msg::ScratchpadReady, which stamps Session::scratchpad. A .lock file in the session dir — deliberately outside the advertised scratchpad/ child, so a stray rm -rf $MERMAID_SCRATCHPAD cannot remove it — is held via File::try_lock for the process lifetime and marks the directory as in use; sweep_stale reaps unlocked directories older than the retention window so abandoned sessions don’t accumulate forever.

Constants§

RETENTION_DAYS
Default retention: unlocked scratchpads older than this are reaped by sweep_stale. mermaidd overrides it via daemon.scratchpad_retention_days.

Functions§

ensure
Create (or adopt) the scratchpad for this project + session id, take its liveness lock, and return the advertised scratchpad/ path. Idempotent — re-running for the same session keeps the already-held lock and returns the same path. If another live process holds the lock (the same conversation open twice), the directory is shared and that process’s lock protects it.
list_text
Bounded ASCII listing of a scratchpad’s contents, for /scratchpad. Deterministic (sorted, directories recursed depth-first), relative paths, human-readable sizes, capped at [MAX_LIST_ENTRIES] lines with an explicit “more” marker. The lock file lives outside the advertised directory, so everything found here is user content.
project_slug
Flatten a project path into a single filesystem-safe component (/home/user/my proj -> -home-user-my-proj). Never empty: a degenerate input falls back to "project".
remove
Remove one session’s scratchpad — the delete-conversation cascade. A directory whose lock is held by a live process is left alone (that session is still open, possibly in another mermaid); the sweep reaps it later.
session_dir
Pure path computation: the locked session dir for (project, session_id) under root. No filesystem access. The advertised scratchpad is its [SCRATCH_SUBDIR] child.
sweep_stale
Reap unheld scratchpads older than retention_days. Returns the number of session directories removed. Runs on session startup (the EnsureScratchpad effect, with RETENTION_DAYS) and on mermaidd startup (with the daemon’s configured retention) — no separate timer.
sweep_stale_in
sweep_stale against an explicit root. Public so mermaidd’s tests (a separate bin target that can’t see pub(crate)) can drive the sweep against a fixture directory, mirroring its bg-log sweep tests.