Undo/redo & rollback system for DSH: every config change is auto-snapshotted; undo/redo/restore to any version from the WebUI or the offline CLI/GUI tools (works even when DSH fails to boot).
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-undo-savepoint
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:lire1131/dsh-undo-savepoint
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A security caretaker for DeepSeek Harness (DSH): every settings change is auto-snapshotted, with one-click undo / redo / restore to any version; proactive health checks, upgrade guarding, and crash rescue; and when DSH won't even boot, the offline WebUI / GUI / CLI still work.
The caretaker checks proactively and speaks only when something is wrong. The first health check completes 30 seconds after startup; after a crash it names the last-known-good snapshot to restore; and when the DSH version changes it takes an upgrade-insurance snapshot before letting the session continue.
Preview
| Conversation header: iconized Undo / Redo / Snapshot / Message-undo buttons + auto-snapshot badge (24 snapshots · 3h ago) |
|---|
| Offline WebUI: crash banner + Undo / Redo / Safe mode / Diagnose / Message undo / Settings — works even when DSH won't boot (snapshot diff & settings: see Offline tools) |
|---|
The caretaker
| Duty | Capability |
|---|---|
| Startup health check | 30 seconds after startup it inspects session directories, tolerance patches, snapshot coverage and disk usage, alerting only on findings |
| Crash rescue | When DSH cannot boot at all, SAFE MODE keeps only this plugin so boot is guaranteed; crash attribution names the last-known-good snapshot for one-click restore |
| Session doctor | undo_scan repairs single-frame layout violations and seq overlaps in session files; what it cannot repair is quarantined, originals untouched |
| Upgrade guard | On a detected DSH version change it takes an upgrade-insurance snapshot, then the first post-upgrade boot produces a compatibility and session-census report |
| Snapshots stay secret | .env, credentials and home-level settings are redacted in snapshots, real values live only in the local vault, export bundles leak nothing |
| Tolerance patches | Runtime fallbacks for known defect points of past DSH builds; they simply stop matching once upstream fixes land, with no functional impact |
Core capabilities
| Capability | What it does |
|---|---|
| Config + plugin-code rollback | Snapshots cover config files AND user-plugin code trees — any broken edit is undoable (incl. pure code incidents like the whale-kit yield* crash); undo / redo / restore-to-any-version from the WebUI, chat or offline CLI |
| Secret redaction + local vault | .env / credentials enter snapshots auto-redacted (structure preserved) — exported ZIPs are safe to share; real values live in a local vault, and local rollbacks restore them fully |
| Time Machine timeline | Snapshot timeline visualization + file-level diff (added/removed line highlighting, per-file navigation, prev/next) + one-click rollback |
| Message-level undo | Records workspace file changes per AI message; say "undo what the last message did" and exactly that is rolled back (before-content restored, new files deleted). Tracked dirs configurable in Settings |
| One-click SAFE MODE | When DSH cannot boot at all, temporarily disables every user plugin except the undo system so it always boots; auto-snapshots + config backup on entry, one-click exit (profile/home dual-level patches backed up & restored; bundle entries that would fail the loader's hard checks are neutralized with the original package.json backed up separately and fully restored on exit) |
| Crash attribution | After an abnormal exit, classifies the crash by log signature (session-corrupt / bundle-check / patch-tree), names the concrete last-known-good snapshot and offers a one-click rollback — no guessing |
| Session-file scan & repair | undo_scan scans <home>/sessions/**/session.jsonl.zstd: single-frame layout violations (the 8/18 crash root cause) and synthetic-closer seq overlap (interrupted-turn seq overlap after undo/snapshot restores) are repaired in place (original kept as .bak + quarantine copy) with triple verification; undecodable files are only isolated, never touched. Offline via dsh-undo.ps1 scan [--fix] (requires Node ≥22.15; degrades to a notice on Node 20) |
| One-click diagnostic & boot preflight | Store side: snapshot store writability, blob integrity (missing/orphan), settings health, snapshot scale. Boot side preflights the hard failures that kill DSH before any plugin is mounted: profile manifest BOM/JSON/shape, every declared dsh.profile.bundles entry resolvable, patchReload value, link: junction targets, duplicate loader ids in patch files, unfinished previous boot. Structured ok/warn/error report; repairable checks are marked [fixable] and can be repaired in one step (undo_doctor fix=true in chat, dsh-undo.ps1 doctor -Fix offline, or the "Repair fixable" button in the standalone WebUI diagnostic panel), with a manual snapshot taken before and an automatic re-check after |
| Safe cross-machine migration | Restore preflights missing plugins and warns clearly; snapshots export/import as one-click ZIP, optional AES-256-GCM encryption (see docs/migration.en.md) |
| Offline emergency kit | WebUI + GUI window + CLI + auto-created desktop shortcut: undo / restore / SAFE MODE / crash banner / rollback log — everything works when DSH is down |
| Auto slimming | Orphan-blob GC (undo_compact) frees disk; size gates keep the plugin tiny (~0.6 MB) with zero runtime dependencies |
Platform support
| Capability | Windows | macOS | Linux |
|---|---|---|---|
| Config/plugin snapshots, undo/redo | ✅ | ✅ | ✅ |
| Offline Web UI (undo-server) | ✅ | ✅ | ✅ |
| Offline CLI / GUI | ✅ (.bat/.ps1) | ✅ (.command) | ✅ (.sh/.desktop) |
| File/dir selection dialog | PowerShell native | osascript | zenity→kdialog (fallback: manual path) |
| CI regression | windows-latest | macos-latest | ubuntu-latest |
Crash rescue quick reference (pick by scenario)
| Scenario | Action |
|---|---|
| Config/plugin mount broken | Chat / WebUI / CLI: undo or restore -Id <id> |
| Plugin code broken | Same — snapshots include plugin code trees, one-click restore |
| Last run crashed, unsure what to roll back to | WebUI / GUI banner shows the last-known-good snapshot, one-click rollback |
| DSH will not boot at all | Desktop "dsh-undo-savepoint" → offline WebUI SAFE MODE button (or CLI safe-mode -Label on) → restart DSH, it always boots |
| Crash banner says session damage | Chat / CLI: undo_scan quarantine=true (or offline dsh-undo.ps1 scan --fix) |
| Missing plugins after restore (cross-machine) | Preflight warning in the restore report; install first or use safe mode |
| "My config suddenly changed" | CLI recent / chat undo_recent check the rollback log |
| Rollback touched plugins/mounts | Report says "restart DSH for it to take effect" |
| SAFE MODE confirmation: disables every user plugin except this one, so DSH always boots — then re-enable them one by one |
|---|
Installation
Prerequisites: DSH (@deepseek-ai/dsh) and Node.js (≥20). The host-mode plugin runs in profiles
that provide the tools / systemPrompt / webServer services (any Web profile qualifies); when DSH
cannot boot at all, use the offline CLI / GUI instead, which does not depend on the host.
Option A (GitHub direct) — install the latest master commit:
dsh plugin --profile web add github:lire1131/dsh-undo-savepoint#master
Restart DSH after installing. Snapshot directories and options are configurable in Settings.
Option C (npm registry) — install from npm:
dsh plugin --profile web add dsh-undo-savepoint
dsh plugin add forwards to pnpm in the profile directory; this package declares
dsh.bundle.patch in its package.json, so it is registered into the profile's bundle list
automatically. Restart DSH to activate.
Option B (local source / pre-release) — clone and mount manually:
- Clone the repository into a local plugins directory (an ASCII path is safer), e.g.
D:\dsh\plugins\dsh-undo-savepoint:
git clone https://github.com/lire1131/dsh-undo-savepoint.git D:\dsh\plugins\dsh-undo-savepoint
- Create a junction so DSH's module resolver can find the local package by name
dsh-undo-savepoint(used by both the host plugin and the WebUI client plugin):
mklink /J "<your-dsh-install>\node_modules\dsh-undo-savepoint" "D:\dsh\plugins\dsh-undo-savepoint"
DSH resolves package names by walking up from its own
node_modules. The default location isC:\Users\<username>\node_moduleswhen npm installed into the user directory; if you run DSH from an npx cache, junction into that cache'snode_modulesinstead. Check the path in DSH's startup error output or runnpm root -g.
- Mount it in the profile patch layer: edit
<DSH_HOME>\profiles\web\cordis.patch.ymland append:
- insert:
- id: dsh-undo-savepoint
name: dsh-undo-savepoint
- Activate: saving hot-reloads the host part; refresh the page to see the header buttons and settings rows; restart DSH for full steady state (legacy flat snapshots migrate automatically).
Dependency note: the host plugin loads
@deepseek-ai/dsh-toolsviacreateRequire('<dsh-install-root>/package.json'). If DSH lives elsewhere, set the environment variableDSH_ROOT=<dsh-install-root>, no extra package installation needed.
Uninstall
Standard uninstall
Two commands; the second cleans up the leftovers:
dsh plugin remove dsh-undo-savepoint
node tools\uninstall.mjs
uninstall.mjs is gentle by default: it removes mount declarations, junctions and the desktop shortcut, and keeps the snapshot library and settings (reinstalling restores your history). When the history is no longer needed, add --purge:
node tools\uninstall.mjs --purge
Common options:
| Option | Effect |
|---|---|
--purge |
Also removes undo\ (settings/state) and undo-snapshots\ (snapshot library) |
--yes |
Skip confirmation (required in non-interactive contexts, prevents scripted deletion) |
--home <dir> |
Override the DSH home directory |
--profile <n> |
Process only the named profile (default: all) |
--json |
Print the cleanup plan as machine-readable JSON |
Without --yes the command first lists every path it will delete and then asks. In a non-interactive context (CI, pipes) it refuses to run unless --yes is given explicitly.
Manual uninstall map
If you really want to clean up by hand, these are the six locations and how to delete each correctly:
| # | Location | Correct removal |
|---|---|---|
| 1 | <dsh-install-root>\node_modules\dsh-undo-savepoint (or under a profile's node_modules) |
Delete the link itself, do not follow it. This is a junction; deleting it is safe. Browsing into it in Explorer and deleting the contents deletes your plugin source |
| 2 | The id: dsh-undo-savepoint entry in <DSH_HOME>\profiles\<profile>\cordis.patch.yml |
Remove that insert entry (or the whole item); an emptied file can be deleted |
| 3 | dsh-undo-savepoint inside dsh.profile.bundles of <DSH_HOME>\profiles\<profile>\package.json |
Remove the entry from the array |
| 4 | <DSH_HOME>\undo\ |
Settings and state (including settings.json). Delete only if you want settings reset |
| 5 | <DSH_HOME>\undo-snapshots\ |
The snapshot library. Confirm you no longer need rollback before deleting |
| 6 | Desktop dsh-undo-savepoint.lnk (macOS .command / Linux .desktop) |
Delete the file |
Windows long-path note
With a deep or non-ASCII Windows user directory, snapshot paths can exceed Explorer's MAX_PATH limit of 260 characters, and a manual delete fails with "file name too long" or leaves a half-deleted mess. Prefer uninstall.mjs: it deletes the fixed set of paths directly without walking into snapshot internals, so the limit does not apply.
Usage (inside DSH)
- Undo: header Undo button /
Ctrl+Alt+Z/ tell the AI "undo the last step" - Redo: Redo button /
Ctrl+Alt+Y(only when nothing changed since the undo) - Manual save: "Save" in the panel / tell the AI "save a snapshot" / CLI
snapshot - Restore to a fixed version: "Restore to this" on a panel row; or tell the AI "restore to "; or CLI
restore -Id <id> - Message-level undo: the header "conversation undo" entry opens the message list; "undo this message" rolls back exactly what that message changed
- Delete a snapshot: "Delete" in the panel; or CLI
remove -Id <id> - Custom shortcuts: Settings → General → Undo/Redo shortcut (click the box then press a combo; Backspace clears)
- Save options: Settings → General → Snapshot Settings (auto-save toggle, debounce, keep count, snapshot dirs, tracked workspace dirs; the 📁 button opens the native folder picker). "Tracked workspace dirs" accepts comma/semicolon-separated paths — non-empty replaces the default working-dir scope
| Message-level undo: pick a message batch, roll back exactly the files it changed |
|---|
Offline tools (work even when DSH won't boot)
WebUI (recommended) — run node tools\undo-server.mjs (or double-click tools\launch-undo.bat / .command / .sh / .desktop); it serves a local 127.0.0.1 page with the timeline / rollback / diff / diagnostics / SAFE MODE. A desktop shortcut is auto-created on plugin load. The diagnostic panel does not only show problems, it repairs them: repairable checks are badged "fixable" and one click on "Repair fixable" fixes them in place, after taking a manual snapshot and with an immediate re-check.
| Desktop shortcut: auto-created on plugin load, double-click to open the offline WebUI |
|---|
| Snapshot diff: file list + change stats (+8 / -2) + line-level highlighting — see every change before rolling back | Offline settings: debounce / retention / redaction mode / dirs / desktop shortcut |
|---|---|
UI language follows your system locale — English UI shown here; Chinese-UI screenshots in README.md.
# GUI window (WinForms): double-click tools\dsh-undo-savepoint-gui.bat, or:
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo-savepoint-gui.ps1"
# CLI
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" list
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" snapshot -Label "reason"
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" undo
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" undo -SyncDeps
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" redo
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" restore -Id <id> -Force
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" restore -Id <id> -Force -SyncDeps
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" remove -Id <id>
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" prune -KeepAuto 20
# Boot preflight (works even when DSH cannot start); -Fix repairs what it can
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" doctor
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-undo.ps1" doctor -Fix
# Safe plugin install (auto snapshots before/after; auto-rollback on failure)
powershell -NoProfile -ExecutionPolicy Bypass -File "tools\dsh-plugin.ps1" add <package>
# 30-line version: open a PowerShell window, paste the whole block, press Enter —
# a "DSH Undo Manager" shortcut appears on the desktop without locating any file
$dshHome = if ($env:DSH_HOME) { $env:DSH_HOME } else { "$env:USERPROFILE\.dsh" }
$d = @("$dshHome\profiles\web\node_modules\dsh-undo-savepoint", "$dshHome\profiles\node_modules\dsh-undo-savepoint", "$env:USERPROFILE\node_modules\dsh-undo-savepoint") | Where-Object { Test-Path (Join-Path $_ 'tools\dsh-undo-savepoint-gui.bat') } | Select-Object -First 1
if ($d) {
$w = New-Object -ComObject WScript.Shell
$s = $w.CreateShortcut((Join-Path ([Environment]::GetFolderPath('Desktop')) 'DSH Undo Manager.lnk'))
$s.TargetPath = Join-Path $d 'tools\dsh-undo-savepoint-gui.bat'
$s.WorkingDirectory = Join-Path $d 'tools'
$s.Save()
Write-Host "Desktop shortcut created: $($s.FullName)"
} else { Write-Host 'Plugin directory not found — install it first: dsh plugin --profile web add github:lire1131/dsh-undo-savepoint#master' }
Typical rescue: DSH fails to boot with something like duplicate loader entry id → open "DSH Undo Manager", pick the snapshot from before the change → Restore → restart DSH. No reinstall, no lost sessions.
UI language: force it with
DSH_UNDO_LANG=zh|en; otherwise Chinese on Chinese hosts, English elsewhere. Applies to the host command output, the offline CLI/GUI, and the WebUI. The single dictionary source islib/i18n/{zh,en}.json(shared by host and WebUI so they cannot drift).
Snapshots & storage
The snapshot captures DSH's boot-critical config: cordis.patch.yml, package.json, cordis.yml, pnpm-workspace.yaml, pnpm-lock.yaml (under the profile) + cordis.patch.yml, settings.yaml, .env, .credentials.yaml (under $DSH_HOME, default ~/.dsh).
When a restore touches package.json / pnpm-lock.yaml, the default behavior only reports that node_modules may be out of sync. To rebuild dependencies, pass -SyncDeps (offline CLI), sync_deps: true (chat tool), or syncDeps: true (REST); the plugin runs pnpm install --frozen-lockfile (plain pnpm install when there is no lockfile). A failed install leaves the restored config files in place.
| Store | Default path (configurable in settings) | Contents |
|---|---|---|
| Manual store | <snapshot root>\manual\ |
Manual snapshots (never auto-pruned) |
| Auto store | <snapshot root>\auto\ |
Auto snapshots, boot baselines, undo pre-restore snapshots (auto keeps latest 20) |
| Legacy store | <snapshot root>\ root |
Old flat layout — still read, auto-migrated on startup |
⚠️ Snapshots contain copies of
.envetc. which may include secrets — do not share or push them.
Multi-profile & custom home
- Profile detection: the plugin reads the active profile from the launch arguments (
dsh --profile mine/--profile=mine;dsh webfalls back toweb); config dir defaults to$DSH_HOME/profiles/<current profile>, and snapshot stores default to<snapshot root>/<current profile>/{auto,manual}(per-profile isolation; the old flat store is still honored so legacy snapshots are never hidden). Offline CLI/GUI cannot see the launch arguments — setDSH_UNDO_PROFILEorprofileNamein settings (defaultweb). - Custom DSH home: the home resolution matches the official launcher (
@deepseek-ai/dsh-home-paths) exactly —$DSH_HOMEwins (blank = unset;~prefixes supported), otherwise<user home>\.dsh; settings file, snapshot root, profile dir and plugin-discovery paths are all derived from it, so third-party clients with a customDSH_HOMEno longer suffer the "two homes" split. - Explicit overrides always win: env vars
DSH_UNDO_SETTINGS/DSH_UNDO_ROOT/DSH_UNDO_EXPORT/DSH_UNDO_PROFILE, config keyshomeDir/profileDir/manualDir/autoDir/profileName.
REST API (backend of the WebUI)
| Endpoint | Description |
|---|---|
GET /api/undo/status |
{canUndo, canRedo, total, bootAlert, safeModeActive, ...} |
GET /api/undo/list |
Snapshot list (with location: manual/auto/legacy) |
GET /api/undo/diff |
?id=<id> file-level structured diff of a snapshot vs current |
GET /api/undo/tree |
Directory-tree grouped diff of a snapshot vs current |
GET /api/undo/doctor |
One-click diagnostic (store writability / blob integrity / settings / scale) plus boot preflight (manifest BOM / bundles / junctions / duplicate loader ids / unfinished previous boot) |
POST /api/undo/doctor/fix |
Repair the fixable boot-preflight findings (strip manifest and patch BOMs, dedupe loader entries by id, recreate missing or dangling plugin junctions); takes a manual snapshot first and returns the repair list plus a re-check report |
GET/POST /api/undo/settings |
Read/write save options; POST applies immediately |
GET /api/undo/messages |
Message-level undo: per-message change list |
POST /api/undo/undo |
Undo the last change; optional body {syncDeps: true} rebuilds node_modules from the restored lockfile |
POST /api/undo/redo |
Redo the last undo; optional body {syncDeps: true} |
POST /api/undo/restore |
body {id, syncDeps?} — restore to a fixed version |
POST /api/undo/message |
body {id} — roll back one message's changes |
POST /api/undo/remove |
body {id} — delete a snapshot |
POST /api/undo/snapshot |
body {reason} — manual save (note/tags supported) |
POST /api/undo/note |
Edit a snapshot's note/tags |
POST /api/undo/prune |
Run expired-snapshot cleanup immediately |
POST /api/undo/compact |
Orphan-blob GC (supports dry_run) |
POST /api/undo/export / POST /api/undo/import |
Export/import all snapshots as ZIP (pure Node, PowerShell-compatible, optional AES-256-GCM password) |
POST /api/undo/safe-mode |
body {on} — enter/exit safe mode |
POST /api/undo/pick-dir / pick-file |
Open the native folder/file picker (per-platform), return the chosen path |
GET /api/undo/locale |
Return the current language (DSH_UNDO_LANG or auto) |
Design notes
- Undo semantics: auto snapshots are taken after a change, so "restoring the newest snapshot" would be a no-op; real undo restores the newest snapshot whose state differs from the current one. When everything matches, a clear "nothing to undo" message is shown instead of pretending.
- Undo can never undo itself: after restoring
cordis.patch.yml, the plugin re-ensures its own mount entry automatically. - Auto-archiving never sabotages undo: the watcher records content hashes of what a restore wrote, so the restore's own file changes are not auto-snapshotted (which would block redo); real changes are snapshotted as usual.
- Format parity: the Node plugin and the PowerShell tools share the same snapshot stores and manifest format; compatible with both Windows PowerShell 5.1 and PowerShell 7.
Development
- Dependency resolution: the host plugin loads
@deepseek-ai/dsh-toolsviacreateRequire(<dsh-install-root>/package.json)(override withDSH_ROOT), no in-repo dependencies required. - Tests (no DSH needed; run in the repository directory):
node tools\smoke-test.mjs :: 189 logic tests (snapshot/undo/redo/store split/no-change hint/message-undo/orphan-GC/zip-interop)
node tools\e2e-watch.mjs :: 10 real-timing regressions (auto-save/undo-no-harm/redo)
node tools\check-size.mjs :: size gate (<5MB)
node tools\check-version.mjs :: semver validation
License
MIT
Links
More in this category
yjh051108/dsh-routing-suite★ 6991
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
strukto-ai/mirage#dsh★ 3674
Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
hust-open-atom-club/oh-dsh★ 326
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
weijiafu14/pi2dsh★ 211
Pi Host ABI compatibility engine: after one install, unmodified Pi extensions from npm mount as native DSH plugins with `dsh plugin add <pi-package>`. Verified end to end on stock DSH with pi-mcp-adapter (full MCP manager: OAuth, resources, prompts, MCP Apps, elicitation, sampling), @tintinweb/pi-subagents, pi-code, pi-hermes-memory and pi-background-tasks; `pi2dsh inspect` reports a package's compatibility before installing.
Fishquito7/dsh-skill-mcp-panel★ 172
Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
kanneiren/dsh-network-settings★ 105
Visualize the DSH process network path on Windows or WSL with layered DNS/TCP/TLS/HTTP probes, detect stale proxy configuration, and apply snapshot-guarded repairs.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.