---
name: context-save
preamble-tier: 2
version: 1.0.0
description: |
  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 /checkpoint — renamed because Claude Code treats /checkpoint as a
  native rewind alias in current environments, which was shadowing this skill.
  (gstack)
allowed-tools:
  - Bash
  - Read
  - Write
  - Glob
  - Grep
  - AskUserQuestion
triggers:
  - save progress
  - save state
  - save my work
  - context save
---

{{PREAMBLE}}

# /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-save` or `/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

```bash
{{SLUG_SETUP}}
```

Collect the current working state:

```bash
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:

1. **What's being worked on** — the high-level goal or feature
2. **Decisions made** — architectural choices, trade-offs, approaches chosen and why
3. **Remaining work** — concrete next steps, in priority order
4. **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:

```bash
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

```bash
{{SLUG_SETUP}}
CHECKPOINT_DIR="$HOME/.gstack/projects/$SLUG/checkpoints"
mkdir -p "$CHECKPOINT_DIR"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
echo "CHECKPOINT_DIR=$CHECKPOINT_DIR"
echo "TIMESTAMP=$TIMESTAMP"
```

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 `{CHECKPOINT_DIR}/{TIMESTAMP}-{title-slug}.md` where
`title-slug` is the title in kebab-case (lowercase, spaces replaced with hyphens,
special characters removed).

The file format:

```markdown
---
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

```bash
{{SLUG_SETUP}}
CHECKPOINT_DIR="$HOME/.gstack/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 gstack skill, not a Claude Code built-in.** When the user types
  `/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.
