End-of-session checklist — commits & pushes uncommitted work, checks service deployments (Vercel, Sanity, Supabase), surfaces what it learned about you, reviews conversation for memories to persist, updates CLAUDE.md, captures deferred work to backlog, logs client-facing decisions, and presents a scannable summary. Use when ending a session.
Session Wrap-Up — Never leave a session with loose ends.
Everything that should happen before you close a session, automated into one command. /wrap-up handles the boring-but-critical end-of-session hygiene so nothing falls through the cracks.
| Step | Action |
|---|---|
| Git | Commits uncommitted work, pushes to remote |
| Services | Checks Vercel, Sanity, Supabase deploy status |
| About you | Surfaces observations about your working style — you approve what gets remembered |
| Memory | Saves project context, feedback, and references to memory |
| CLAUDE.md | Updates project instructions if the session revealed new patterns |
| Checklists | Marks completed items in active plans |
| Backlog | Captures deferred work, TODOs, and ideas you didn't act on |
| Decisions | Logs product/design/technical decisions in a client-readable format |
| Summary | What was done, what's next, what's open |
/wrap-up
No arguments. Just run it before closing.
End-of-session checklist. Run every check below, execute the actions, and present a summary to the user before they close the session.
Before starting the skill, check if claude-skills has an update available. This should be fast and non-blocking — use cached results when possible.
_CS_STATE="$HOME/.claude-skills"
mkdir -p "$_CS_STATE"
# Skip if checks disabled
if [ -f "$_CS_STATE/update-check" ] && [ "$(cat "$_CS_STATE/update-check")" = "false" ]; then
echo "UPDATE_CHECK_DISABLED"
exit 0
fi
# Skip if snoozed
if [ -f "$_CS_STATE/update-snoozed" ]; then
_SV=$(awk '{print $1}' "$_CS_STATE/update-snoozed")
_SL=$(awk '{print $2}' "$_CS_STATE/update-snoozed")
_ST=$(awk '{print $3}' "$_CS_STATE/update-snoozed")
_NOW=$(date +%s)
case "$_SL" in 1) _D=86400;; 2) _D=172800;; *) _D=604800;; esac
if [ $((_NOW - _ST)) -lt "$_D" ]; then
echo "SNOOZED until $(date -d @$((_ST + _D)) '+%Y-%m-%d %H:%M' 2>/dev/null || echo 'later')"
exit 0
fi
fi
# Get installed version
_INSTALLED=$(cat "$HOME/.claude/skills/wrap-up/VERSION" 2>/dev/null || echo "0.0.0")
# Use cache if fresh (24h TTL)
_CACHE="$_CS_STATE/last-update-check"
if [ -f "$_CACHE" ]; then
_CT=$(awk 'NR==1{print $1}' "$_CACHE")
_NOW=$(date +%s)
if [ $((_NOW - _CT)) -lt 86400 ]; then
cat "$_CACHE" | tail -n +2
exit 0
fi
fi
# Find repo and fetch
_CS_REPO=""
# Check pointer file first (contains repo path)
if [ -f "$_CS_STATE/repo" ]; then
_PTR=$(cat "$_CS_STATE/repo" | tr -d '[:space:]')
[ -d "$_PTR/.git" ] && _CS_REPO="$_PTR"
fi
# Fall back to well-known locations
if [ -z "$_CS_REPO" ]; then
for _C in "$HOME/claude-skills" "$HOME/projects/claude-skills" "$HOME/dev/claude-skills" "$HOME/src/claude-skills" "$HOME/code/claude-skills"; do
[ -d "$_C/.git" ] && _CS_REPO="$_C" && break
done
fi
if [ -z "$_CS_REPO" ]; then
echo "NO_REPO"
exit 0
fi
cd "$_CS_REPO"
git fetch origin --quiet 2>/dev/null
_REMOTE=$(git show origin/main:VERSION 2>/dev/null | tr -d '[:space:]')
_NOW=$(date +%s)
if [ -n "$_REMOTE" ] && [ "$_INSTALLED" != "$_REMOTE" ]; then
_RESULT="UPGRADE_AVAILABLE $_INSTALLED $_REMOTE $_CS_REPO"
else
_RESULT="UP_TO_DATE $_INSTALLED"
fi
printf "%s\n%s\n" "$_NOW" "$_RESULT" > "$_CACHE"
echo "$_RESULT"
If UPGRADE_AVAILABLE {old} {new} {repo}:
First, read the changelog to build a short summary of what's new:
cd "{repo}"
git show origin/main:CHANGELOG.md 2>/dev/null || echo "(no changelog)"
From the changelog, extract changes between v{old} and v{new}. Compose a one-line summary of 20 words or fewer describing the most interesting user-facing changes. This is the {whats_new} summary.
Check auto-upgrade preference:
_AUTO=""
[ -f "$HOME/.claude-skills/auto-upgrade" ] && _AUTO=$(cat "$HOME/.claude-skills/auto-upgrade")
echo "AUTO_UPGRADE=$_AUTO"
If AUTO_UPGRADE=true: Log "Auto-upgrading claude-skills v{old} -> v{new}... ({whats_new})" and run the upgrade (see below). If it fails, warn and continue with the skill.
Otherwise, use AskUserQuestion:
| Response | Action |
|---|---|
| Yes, upgrade now | Run upgrade below |
| Always keep me up to date | echo "true" > "$HOME/.claude-skills/auto-upgrade" — tell user auto-upgrade enabled, then run upgrade |
| Not now | Write snooze: echo "{new} {level} $(date +%s)" > "$HOME/.claude-skills/update-snoozed" (level 1=24h, 2=48h, 3+=1wk). Tell user when next reminder will be. Continue with the skill. |
| Never ask again | echo "false" > "$HOME/.claude-skills/update-check" — tell user checks disabled. Continue with the skill. |
Upgrade steps:
cd "{repo}"
_OLD=$(cat VERSION 2>/dev/null || echo "unknown")
git stash 2>&1
git pull origin main --ff-only 2>&1 || git reset --hard origin/main
bash install.sh
rm -f "$HOME/.claude-skills/update-snoozed"
echo "$_OLD" > "$HOME/.claude-skills/just-upgraded-from"
After upgrading, read {repo}/CHANGELOG.md, summarize changes between old and new versions as 3-7 bullets, then display:
claude-skills v{new} — upgraded from v{old}!
What's new:
- ...
Happy skilling!
Then continue with the skill below.
If UP_TO_DATE, SNOOZED, UPDATE_CHECK_DISABLED, or NO_REPO: Continue silently with the skill.
Run git status and git log @{upstream}..HEAD --oneline 2>/dev/null (to check unpushed commits).
Report:
If there are uncommitted changes, ask the user whether to commit and push. Use AskUserQuestion with options: "Commit & push", "Commit only", "Skip — I'll handle it". If the user chooses to commit, use a descriptive message summarizing the session's work.
After pushing, check and report on all connected services:
vercel ls --limit 1 to confirm latest deployment status.npx sanity@latest schema deploy (or offer to run it). If no schema changes, report "No Sanity schema changes."Report the status of each service, or "No updates needed" for services unaffected by the session.
Before saving any memories, present what you observed about the user this session. This is the most important part of wrap-up — the user should see themselves reflected back and approve what gets remembered.
How to surface observations:
Review the full conversation and identify:
The distinction that matters: Actions are evidence, not observations. "You batched 3 related backlog items" is a summary of what happened. "You think in dependency chains, not priority lists" is an insight about who you are. Only surface insights — things that change how I should work with you in future sessions.
Bad: "You picked up 3 backlog items and asked me to fix them all" (action replay) Good: "You have zero tolerance for deferred cleanup — when you see tech debt, you want it gone now, not next session" (personality insight that changes my behavior)
Only include observations that would actually change how you work with this person.
Present via interactive multi-select using AskUserQuestion:
Use AskUserQuestion with multiSelect: true. Each observation becomes one option:
Example option:
If the session revealed nothing new about the user, skip the AskUserQuestion entirely and report "Nothing new to report about your working style this session."
After the user selects, save only the selected observations to the appropriate memory files. Do NOT save before approval.
After the user observations are handled, review the conversation for project-level memories:
About the project (save to project memory):
Memories have two scopes:
~/.claude/projects/<project>/memory/) — project context, references, project-specific patterns~/.claude/memory/) — user preferences, feedback, working style, anything that applies across all projectsRouting rule: user and feedback type memories go to global memory by default. project and reference type memories go to project memory. If unsure, ask: "does this apply to just this project, or everywhere?"
For each potential memory:
Project and feedback memories can be saved automatically (they're about the project, not the person). Report what was saved.
Consider whether any project-level CLAUDE.md updates are needed based on the session.
Only add to CLAUDE.md if ALL of these are true:
Never add:
Size check: If project CLAUDE.md exceeds ~120 lines, review for items that can be cut before adding new ones. CLAUDE.md should stay concise — bloat causes Claude to ignore instructions.
Also check the global ~/.claude/CLAUDE.md if session-wide learnings apply across projects — same filtering rules apply.
Update CLAUDE.md automatically if changes pass the filter above. Report what was updated, or "No CLAUDE.md updates needed."
If the session involved working through a checklist or plan (e.g., docs/plans/*-checklist.md), check:
[x]?Report what was checked off, or "No active checklists affected."
Review the session for potential backlog items — deferred work, rolled-back features, bugs noticed in passing, ideas discussed but not acted on, TODOs mentioned but not completed. Don't add items that are already in the backlog.
Present via interactive multi-select using AskUserQuestion:
Use AskUserQuestion with multiSelect: true. Each candidate backlog item becomes one option:
If there are no backlog candidates, skip the AskUserQuestion entirely and report "Nothing to add to the backlog."
After the user selects, append only the selected items to BACKLOG.md in the project root, grouped under an appropriate category heading. Use - [ ] checkbox format.
Review the session for product, design, and technical decisions that the client should know about. If decisions were made, write a client-facing decision log.
Skip if: The session was pure implementation with no decisions (just coding what was already decided), or only involved internal cleanup/refactoring with no client-visible impact.
When to write:
How to write:
docs/decisions/YYYY-MM-DD-<topic>.md (create docs/decisions/ if it doesn't exist)Present to the user: "I found N decisions from this session. Writing the client decision log to docs/decisions/.... Want to review before I save?"
Provide a brief summary:
Present the report, then the two interactive selectors, then the summary. The flow is:
multiSelect: true. Combine both into one call so the user sees them together.## Wrap-Up Report
### Git
- Branch: ...
- Uncommitted: ... (or clean)
- Pushed: ... (or already in sync)
### Services
- Vercel: [deploying / no push needed]
- Sanity: [schema deployed / no changes]
- Supabase: [migration applied / no changes]
### CLAUDE.md
- [updated/no changes] ...
### Checklists
- [updated/no active checklists] ...
### Project Memory
- [saved/updated/none] ...
### Client Decision Log
- [written to docs/decisions/... / no decisions this session]
[AskUserQuestion with up to 2 multi-select questions:
Q1 header:"Remember" — "What should I remember about you?" — insights as options
Q2 header:"Backlog" — "What should go in the backlog?" — deferred items as options
Skip either question if there are no candidates for it.]
### Summary
- Done: ...
- Next: ...
- Open: ...
After presenting the report, ask: "Anything else before closing?" and wait for the user to confirm before considering the session complete.