context-save
Save working context. Captures git state, decisions made, and remaining work so any future session can pick up without losing a beat. Use when asked to "save progress", "save state", "context save", or "save my work". Pair with /context-restore to resume later. Formerly /checkpoi
What it does
Preamble
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
/context-save — Save Working Context
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.
Detect command
Parse the user's input to determine the mode:
/context-saveor/context-save <title>→ Save/context-save list→ List
If 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."
Save flow
Step 1: Gather state
eval "$(~/.vibestack/bin/vibe-slug 2>/dev/null)" && mkdir -p ~/.vibestack/projects/$SLUG
Collect 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/null
Step 2: Summarize context
Using the gathered state plus your conversation history, produce a summary covering:
- What's being worked on — the high-level goal or feature
- Decisions made — architectural choices, trade-offs, approaches chosen and why
- Remaining work — concrete next steps, in priority order
- Notes — anything a future session needs to know (gotchas, blocked items, 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.
Step 3: Compute session duration
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"
fi
If the duration cannot be determined, omit the session_duration_s field from the
saved file.
Step 4: Write saved-context 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.
List flow
Step 1: Gather saved contexts
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"
fi
Step 2: Display table
Default 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."
Important Rules
- Never modify code. This skill only reads state and writes the context file.
- Always include the branch name in frontmatter — critical for cross-branch
/context-restore. - Saved files are append-only. Never overwrite or delete existing files. Each save creates a new file.
- Infer, don't interrogate. Use git state and conversation context to fill in the file. Only use AskUserQuestion if the title genuinely cannot be inferred.
- This is a vibestack skill, not a Claude Code built-in. When the user types
/context-save, invoke this skill via the Skill tool. The old/checkpointname collided with Claude Code's native/rewindalias — the rename fixed that.
Capabilities
Install
Quality
deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 15 github stars · SKILL.md body (8,541 chars)