From session-management
This skill should be used whenever the user invokes `/session-management:handoff` or signals that the session is wrapping up — phrases like "let's wrap up", "end of session", "save state", "save this", "remember this", "checkpoint", "checkpoint this", "save progress", "write this down", "before we run out of context", "before I close my laptop", "switching machines", "pause here", "that's a wrap for today", "I'm out of time", "let's continue tomorrow", "compact incoming", "goodnight", "ttyl", "EOD", "logging off", "shutting down", "I need to stop here", "I need to step away", "see you Monday", "have a good weekend", "brb", or task-completion signals like "shipped it", "PR is merged", "feature is done", "that's the last todo", "save handoff", "do a handoff", "write the handoff", "summarize what we did today", "write up the session", "park this", "save state for tomorrow", "merged", "deployed", "released", "tagged", "snapshot this", "dump state", "before I forget", "context is getting full", "before the context window fills", "running low on context", "before /clear", or before a planned context compaction (whether user-invoked `/compact` or a harness low-context warning), or after `/clear` is announced. It writes every load-bearing piece of session knowledge into the project's Obsidian folder, structured per the documentation manual bundled with this plugin (Diátaxis categories, descriptive titles, split/merge rules). Project state lives in Obsidian, never in the repo working tree, and never bloated into CLAUDE.md.
How this skill is triggered — by the user, by Claude, or both
Slash command
/session-management:handoffThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Capture every load-bearing piece of session knowledge into the project's Obsidian folder so the next session can pick up productively from turn one. Overlap with CLAUDE.md is fine — same fact, different depth, different audience. See Step 1 for why the Obsidian-only routing is non-negotiable.
Capture every load-bearing piece of session knowledge into the project's Obsidian folder so the next session can pick up productively from turn one. Overlap with CLAUDE.md is fine — same fact, different depth, different audience. See Step 1 for why the Obsidian-only routing is non-negotiable.
Walk the steps in order. Skip a step only if its output would be empty, and say so explicitly in the final report.
Read ${CLAUDE_PLUGIN_ROOT}/references/documentation_tutorial_manual.md (the manual bundled with this plugin) via the Read tool now. It is the contract for how every page is shaped — Diátaxis (the four-category documentation framework: Tutorial / How-to / Reference / Explanation) categories, page structure, split/merge rules, ADR naming, hierarchy depth.
If the manual file is missing at the expected path, tell the user the plugin's reference is missing. The skill can still proceed: page_template.md (loaded at Step 6) carries the authoritative filename, frontmatter, and write-routing conventions, and Step 5 below states the Diátaxis category rule. Don't silently improvise shapes those references don't cover.
Look for mcp__obsidian__* tools in the current session. If they are absent, stop and tell the user the Obsidian MCP is not connected, with the error if any. Do not write a local-file fallback under any circumstance — cross-machine sync is the entire point of routing state through Obsidian, and a quiet local fallback would let state diverge silently.
Convention: claude/<cwd-basename>. Get the basename via Bash (e.g. basename "$PWD") and use that for every path below. Example: cwd G:/projects/pgatzka-skills → folder claude/pgatzka-skills.
The Obsidian MCP creates the folder implicitly on the first obsidian_write_note, so no explicit "create folder" call is needed.
Call obsidian_list_notes on the project folder. Note what already exists and infer each page's Diátaxis category from its title. This is the basis for deciding whether new session content extends an existing page or creates a new one.
If obsidian_list_notes errors (not because the folder is empty — that's a normal result — but because the MCP throws): report the error in the final handoff report and continue with the folder assumed empty, not verified empty. Prior pages may exist at filenames the failed call would have surfaced, so probe each Step 6 target with obsidian_get_note before writing a new page. If get_note returns content, the response depends on the page kind: for Reference-style pages (where the page-template routing is "merge"), switch the write to a get_note+reconcile+overwrite merge instead of creating a duplicate; for snapshot-overwrite pages (the project root index, current-state pages), apply Step 7's content sanity-check before deciding to overwrite; for ADRs, the dated filename should already disambiguate, so the probe is just a safety net. If get_note returns not-found, the path is genuinely free. Don't escalate to a full halt unless Step 1's MCP-availability check would also now fail; a transient error on a single call shouldn't abort an otherwise-completable handoff.
Read ${CLAUDE_PLUGIN_ROOT}/skills/handoff/references/completeness_checklist.md via the Read tool now, before proceeding. The checklist covers ten categories: project overview, current state, open tasks, open questions, decisions made this session, tech-stack changes, new/extended features, gotchas and dead ends, conventions learned, and next-session orientation — plus the rule for flagging CLAUDE.md-candidate items without modifying CLAUDE.md.
For each item in the loaded checklist, capture content from this session or write "nothing this session" — never fabricate, because the next session orients off this report and a fabricated item costs more than a missing one.
For each item from Step 4:
obsidian_get_note to peek at any existing page before deciding to extend or supersede — that's the same call Step 6's merge flow uses, so the read is reusable.page_template.md (loaded in Step 6).ADR - YYYY-MM-DD - <decision>.md. See ${CLAUDE_PLUGIN_ROOT}/skills/handoff/references/page_template.md for the full conventions and write-call routing — load it in Step 6.Read ${CLAUDE_PLUGIN_ROOT}/skills/handoff/references/page_template.md via the Read tool now, before writing any page. It contains the page shape, the filename conventions per page kind (index / sub-page / ADR), the write-call routing (new / overwrite / append / merge / ADR), and the per-call Obsidian-failure handling. Apply the rules there to every page in this step.
Path: claude/<basename>/<basename>.md (e.g. claude/pgatzka-skills/pgatzka-skills.md). The filename matches the project basename exactly so pickup can resolve it. Overwrite on every handoff — this is the snapshot, not a log.
Before overwriting, sanity-check that the existing file at that path is actually a prior handoff index. Call obsidian_get_note on the path. Distinguish three outcomes the same way pickup Step 3 does:
Content sanity-check (call succeeded, file exists): treat the file as a valid prior index if it contains (Current state heading OR Open tasks heading) AND a Pages in this project (or equivalent links) section — this is the exact same check pickup Step 3 runs, so a single file can't be classified differently on the two sides of the round-trip. If those markers are present, proceed with the overwrite. If they are missing, a same-named non-index note may be sitting there — ask the user via an AskUserQuestion call that complies with the structured-questions sister plugin. Compliant payload shape:
{
"questions": [{
"question": "A file already exists at the index path but doesn't look like a handoff index. What should I do?",
"header": "Index collision",
"options": [
{ "label": "Replace it (Recommended)",
"description": "Pros: the index lands where pickup expects it; one canonical entry point for this project. Cons: the existing content at that path is overwritten — if it was something else you wanted to keep, it's gone." },
{ "label": "Write alongside under a new name",
"description": "Pros: preserves the existing file. Cons: pickup looks at the basename path; the new index won't be found unless you rename one of them later." },
{ "label": "Abort the handoff",
"description": "Pros: nothing is written; you can inspect the situation manually. Cons: the session's state isn't captured anywhere — running handoff later may have the same collision." }
]
}]
}
This mirrors the defense pickup does on the read side and prevents silently destroying unrelated content.
Required sections (this is the handoff↔pickup contract — pickup Step 3 sanity-checks the file by looking for at least "Current state" or "Open tasks", plus "Pages in this project". If you rename or drop these section headings here, also update the matching check in pickup/SKILL.md Step 3 to keep the round-trip intact):
[[Descriptive Title]].Output a structured report:
Then stop. Do not start new implementation work — the session is wrapping up.
Re-read the relevant section of the manual or the skill references at ${CLAUDE_PLUGIN_ROOT}/skills/handoff/references/. Default to splitting over merging; default to descriptive titles over short ones; default to writing the page over skipping — if it's not in Obsidian, the next session can't find it.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub pgatzka/pgatzka-marketplace --plugin session-management