syssnap - System State Snapshot Generator¶
Creates a timestamped manifest of your Zshand environment for backup, migration, or debugging.
Overview¶
syssnap writes a single Markdown file that captures machine identity, tool versions, ZSHAND_* configuration (from env.zsh or .env), and active keybindings. The output path is copied to the clipboard when a clipboard tool is available (wl-copy, pbcopy, xclip, or xsel).
When to use: Before major changes, when migrating to a new machine, or to document your current setup for support or comparison with diffenv.
Usage¶
Options¶
-h,--help— Show help (to stderr) and exit.
No other options. Output file is always PROJECT_ROOT/backups/manifest_YYYYMMDD_HHMMSS.md (or ZSHAND/backups/ if PROJECT_ROOT is unset).
Examples¶
# Create snapshot before major changes
syssnap
# Before migrating to new machine
syssnap
# Copy the generated file (path is in clipboard) to the new machine
# Compare with another manifest later
syssnap
diffenv manifest_20260201_120000.md manifest_20260202_120000.md
How It Works¶
- Base path — Uses
PROJECT_ROOTorZSHAND(derived from script location if unset). - Output — Creates
backups/manifest_YYYYMMDD_HHMMSS.mdunder that base. Directory is created if needed. - Sections written:
- Header and environment (machine ID, OS).
- Toolchain versions for: zsh, fzf, jq, wl-copy, cliphist (or "NOT FOUND").
- ZSHAND*variables from
$ZSHAND_CONFIG_DIR/env.zshif present, else frombase/.env(only ZSHAND* lines; other vars omitted for privacy). - Keybinding audit (bindkey lines matching vbuffer, copybuffer, aiexplain, qlog, sudo).
- Clipboard — Copies the manifest file path using the first available of: wl-copy (Wayland), pbcopy (macOS), xclip, xsel (X11).
Configuration¶
No config file. Behavior depends on environment:
| Variable / path | Effect |
|---|---|
PROJECT_ROOT or ZSHAND | Base directory; output is {base}/backups/manifest_*.md. |
ZSHAND_CONFIG_DIR | When set, ZSHAND_* are read from $ZSHAND_CONFIG_DIR/env.zsh if that file exists. |
base/.env | If env.zsh is not used, ZSHAND_* are read from {base}/.env (e.g. from envconsolidate). |
ZSHAND_MACHINE_ID, MACHINE_ID | Machine name in the manifest (default: hostname -s). |
ZSHAND_OS | OS identifier in the manifest (default: unknown). |
Dependencies¶
- Required:
date,bindkey(zsh built-in). Framework typically providesPROJECT_ROOT/ZSHANDviacore/02_vars.zshwhen loaded. - Optional: One of wl-copy, pbcopy, xclip, xsel for copying the output path to the clipboard.
- Version checks: zsh, fzf, jq, wl-copy, cliphist (missing tools show as "NOT FOUND" in the manifest).
Troubleshooting¶
"PROJECT_ROOT and ZSHAND are unset"¶
Run from a shell that has loaded Zshand, or run from the repo so the script can derive ZSHAND from its own path. If you run without loading the framework, the script still tries to set ZSHAND from dirname "$0"/...
"Could not create directory" / "Could not write manifest"¶
Check permissions and disk space for PROJECT_ROOT/backups (or ZSHAND/backups). The script uses mkdir -p and fails with a clear message if the directory or file cannot be created.
No ZSHAND_* in the manifest¶
- If you use the framework’s config: ensure
ZSHAND_CONFIG_DIRis set andenv.zshexists there and containsZSHAND_*lines. - If you use a
.envin the repo/base: ensurebase/.envexists and containsZSHAND_*lines (e.g. from envconsolidate).
Path not copied to clipboard¶
Install one of: wl-copy (Wayland), pbcopy (macOS), xclip, or xsel (X11). The script does not fail if clipboard copy fails; it only prints the manifest path to stdout.