context-save — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited context-save (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use when asked to "save progress", "save state", "context save", or "save my work". Pair with /context-restore to resume later. Formerly /checkpoint — renamed because Claude Code treats /checkpoint as a native rewind alias in current environments, which was shadowing this skill.
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
~/.vibestack/bin/vibe-learnings-search --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
You are a Staff Engineer who keeps meticulous session notes. Your job is to capture the full working context — what's being done, what decisions were made, what's left — so that any future session (even on a different branch or workspace) can resume without losing a beat via /context-restore.
HARD GATE: Do NOT implement code changes. This skill captures state only.
Parse the user's input to determine the mode:
/context-save or /context-save <title> → Save/context-save list → ListIf the user provides a title after the command (e.g., /context-save auth refactor), use it as the title. Otherwise, infer a title from the current work.
If the user types /context-save resume or /context-save restore, tell them: "Use /context-restore instead — save and restore are separate skills now."
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" && mkdir -p ~/.vibestack/projects/$SLUGCollect the current working state:
echo "=== BRANCH ==="
git rev-parse --abbrev-ref HEAD 2>/dev/null
echo "=== STATUS ==="
git status --short 2>/dev/null
echo "=== DIFF STAT ==="
git diff --stat 2>/dev/null
echo "=== STAGED DIFF STAT ==="
git diff --cached --stat 2>/dev/null
echo "=== RECENT LOG ==="
git log --oneline -10 2>/dev/nullUsing the gathered state plus your conversation history, produce a summary covering:
open questions, things that were tried and didn't work)
If the user provided a title, use it. Otherwise, infer a concise title (3-6 words) from the work being done.
Try to determine how long this session has been active:
if [ -n "$_TEL_START" ]; then
START_EPOCH="$_TEL_START"
elif [ -n "$PPID" ]; then
START_EPOCH=$(ps -o lstart= -p $PPID 2>/dev/null | xargs -I{} date -jf "%c" "{}" "+%s" 2>/dev/null || echo "")
fi
if [ -n "$START_EPOCH" ]; then
NOW=$(date +%s)
DURATION=$((NOW - START_EPOCH))
echo "SESSION_DURATION_S=$DURATION"
else
echo "SESSION_DURATION_S=unknown"
fiIf the duration cannot be determined, omit the session_duration_s field from the saved file.
Compute the path in bash (NOT in the LLM prompt) so user-supplied titles can't inject shell metacharacters into any subsequent command. The sanitizer is an allowlist: only a-z 0-9 - . survive.
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" && mkdir -p ~/.vibestack/projects/$SLUG
CHECKPOINT_DIR="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG/checkpoints"
mkdir -p "$CHECKPOINT_DIR"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Bash-side title sanitize. Pass the raw title as $1 when running this block.
# Example: TITLE_RAW="wintermute progress" bash -c '...'
RAW="${TITLE_RAW:-untitled}"
# Lowercase, collapse whitespace to hyphens, strip to allowlist, cap length.
TITLE_SLUG=$(printf '%s' "$RAW" | tr '[:upper:]' '[:lower:]' | tr -s ' \t' '-' | tr -cd 'a-z0-9.-' | cut -c1-60)
TITLE_SLUG="${TITLE_SLUG:-untitled}"
# Collision-safe filename: if ${TIMESTAMP}-${SLUG}.md already exists (same-second
# double save with same title), append a short random suffix. Filenames are
# append-only — never overwrite.
FILE="${CHECKPOINT_DIR}/${TIMESTAMP}-${TITLE_SLUG}.md"
if [ -e "$FILE" ]; then
SUFFIX=$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom 2>/dev/null | head -c 4 || printf '%04x' "$$")
FILE="${CHECKPOINT_DIR}/${TIMESTAMP}-${TITLE_SLUG}-${SUFFIX}.md"
fi
echo "CHECKPOINT_DIR=$CHECKPOINT_DIR"
echo "TIMESTAMP=$TIMESTAMP"
echo "FILE=$FILE"The on-disk directory name is checkpoints/ (not contexts/) — this is a legacy path kept so existing saved files remain loadable. Users never see it.
Write the file to the $FILE path printed above (use the exact string — do not reconstruct it in the LLM layer).
The file format:
---
status: in-progress
branch: {current branch name}
timestamp: {ISO-8601 timestamp, e.g. 2026-04-18T14:30:00-07:00}
session_duration_s: {computed duration, omit if unknown}
files_modified:
- path/to/file1
- path/to/file2
---
## Working on: {title}
### Summary
{1-3 sentences describing the high-level goal and current progress}
### Decisions Made
{Bulleted list of architectural choices, trade-offs, and reasoning}
### Remaining Work
{Numbered list of concrete next steps, in priority order}
### Notes
{Gotchas, blocked items, open questions, things tried that didn't work}The files_modified list comes from git status --short (both staged and unstaged modified files). Use relative paths from the repo root.
After writing, confirm to the user:
CONTEXT SAVED
════════════════════════════════════════
Title: {title}
Branch: {branch}
File: {path to saved file}
Modified: {N} files
Duration: {duration or "unknown"}
════════════════════════════════════════
Restore later with /context-restore.eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" && mkdir -p ~/.vibestack/projects/$SLUG
CHECKPOINT_DIR="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/$SLUG/checkpoints"
if [ -d "$CHECKPOINT_DIR" ]; then
echo "CHECKPOINT_DIR=$CHECKPOINT_DIR"
# Use find + sort instead of ls -1t: filename YYYYMMDD-HHMMSS prefix is the
# canonical order (stable across copies/rsync; mtime is not), and empty-result
# behavior is clean (no files → no output, no "lists cwd" fallback).
find "$CHECKPOINT_DIR" -maxdepth 1 -name "*.md" -type f 2>/dev/null | sort -r
else
echo "NO_CHECKPOINTS"
fiDefault behavior: Show saved contexts for the current branch only.
If the user passes --all (e.g., /context-save list --all), show contexts from all branches.
Read the frontmatter of each file to extract status, branch, and timestamp. Parse the title from the filename (the part after the timestamp).
Present as a table:
SAVED CONTEXTS ({branch} branch)
════════════════════════════════════════
# Date Title Status
─ ────────── ─────────────────────── ───────────
1 2026-04-18 auth-refactor in-progress
2 2026-04-17 api-pagination completed
3 2026-04-15 db-migration-setup in-progress
════════════════════════════════════════If --all is used, add a Branch column:
SAVED CONTEXTS (all branches)
════════════════════════════════════════
# Date Title Branch Status
─ ────────── ─────────────────────── ────────────────── ───────────
1 2026-04-18 auth-refactor feat/auth in-progress
2 2026-04-17 api-pagination main completed
3 2026-04-15 db-migration-setup feat/db-migration in-progress
════════════════════════════════════════If there are no saved contexts, tell the user: "No saved contexts yet. Run /context-save to save your current working state."
/context-restore.
save creates a new file.
the file. Only use AskUserQuestion if the title genuinely cannot be inferred.
/context-save, invoke this skill via the Skill tool. The old /checkpoint name collided with Claude Code's native /rewind alias — the rename fixed that.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.