session-management
Manage work sessions with creation, loading, syncing, and archiving capabilities.
SKILL.mdskills/session-management/SKILL.md
GitHubSession Management
Manages work sessions. Session paths must be explicitly provided or known from context.
Session Path Resolution
IMPORTANT: Sessions do NOT have a default location. The session path must be:
- Provided explicitly in arguments (e.g.,
start ~/projects/my-project/_sessions/session-name) - Already known from conversation context (active session in working memory)
- Defined in project's
.samocodefile underSESSIONSpath
If session path cannot be determined: STOP and ask the user for the session location.
Finding .samocode: Look in current working directory (where the provider CLI was started). Never guess paths - if .samocode not found, ask user.
Repository Resolution
IMPORTANT: All git operations (fetch, branch creation, worktree management) MUST run from the correct repository directory.
- Read
.samocodefrom CWD — useMAIN_REPOvalue as the repo directory for all git commands - If
.samocodenot found orMAIN_REPOnot set: fall back togit rev-parse --show-toplevelfrom CWD - Never run git branch/worktree/fetch commands from CWD directly — always resolve and use the repo directory first
- Store the resolved repo path alongside the session for use in all actions
Actions
Use $ARGUMENTS to specify action and parameters:
start [session-path/name]- Create new sessioncontinue [session-name-pattern]- Load existing sessionsync- Sync current conversation to active sessionarchive [session-name-pattern]- Archive a session
Action: start
Create a new work session.
Steps
Resolve session location:
- If full path provided in arguments: use it
- If only name provided: read
.samocodefrom current working directory, useSESSIONSpath - If
.samocodenot found: STOP and ask user - never guess or create arbitrary folders
Parse session name:
- Take session name from arguments after "start"
- If empty, ERROR: "Session name required. Usage: start [session-name]"
- Sanitize name (lowercase, replace spaces with hyphens)
Create session folder:
- Path:
[SESSIONS_DIR]/[YY-MM-DD]-[session-name]/(use current date for folder name) - If folder exists, ERROR: "Session already exists"
- Path:
Create worktree (if
.samocodehas WORKTREES):Read
MAIN_REPOandWORKTREESfrom.samocode. If both are set, create a worktree:# Derive branch name: strip date prefix from session folder name # e.g., "26-02-05-my-feature" -> "my-feature" BRANCH_NAME=[session-name] # the name before date-prefixing # If GIT_BRANCH_PREFIX env var is set, prepend it: [prefix]/[branch-name] # Fetch and detect default branch cd [MAIN_REPO] git fetch origin DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d: -f2 | xargs) # Create worktree from remote default branch git worktree add -b [BRANCH_NAME] [WORKTREES]/[YY-MM-DD]-[session-name] origin/$DEFAULT_BRANCH # Point upstream at the branch's own remote ref. `-b` from origin/$DEFAULT_BRANCH # inherits the default branch's tracking: bare `git pull` would merge it in, and PR # tooling (gh, octo.nvim) reads @{u} to detect the PR branch. The remote ref # appears on first `git push`. git config branch.[BRANCH_NAME].remote origin git config branch.[BRANCH_NAME].merge refs/heads/[BRANCH_NAME]If worktree creation fails (branch already exists), try attaching to existing branch:
git worktree add [WORKTREES]/[YY-MM-DD]-[session-name] [BRANCH_NAME] # Normalize upstream the same way — pre-existing branches may track origin/$DEFAULT_BRANCH git config branch.[BRANCH_NAME].remote origin git config branch.[BRANCH_NAME].merge refs/heads/[BRANCH_NAME]Working Dir =
[WORKTREES]/[YY-MM-DD]-[session-name]Restore gitignored env files in the worktree (
git worktree adddoes not copy gitignored files):- If the project relies on a
.env(or per-service.env) that lives outside git, copy it from the main repo, or seed it from a secrets store. Path layout is project-specific — checkMAIN_REPO's.env*files and the project README.
Run the project's per-worktree setup hook (if present): some projects need per-worktree setup beyond env files (LSP config, editable-install shims). If an executable hook exists at
[PROJECT_DIR]/.claude/hooks/post-worktree-create.sh— where[PROJECT_DIR]is the directory containing.samocode— run it with the new worktree path. Non-fatal: log any failure and continue.HOOK="[PROJECT_DIR]/.claude/hooks/post-worktree-create.sh" [ -x "$HOOK" ] && "$HOOK" "[Working Dir]" || trueIf WORKTREES not set (non-repo project): fall back to
MAIN_REPO, orgit rev-parse --show-toplevel, or current directory.- If the project relies on a
Create _overview.md:
# Session: [session-name] Started: [TIMESTAMP_LOG] Working Dir: [worktree-path or fallback] ## Status Phase: investigation Iteration: 1 Blocked: no Last Action: Session created Next: Ready to work ## Flow Log - [TIMESTAMP_ITERATION] Session created ## Files (none yet) ## Plans (none yet) ## Linear Tasks (none yet)Phaseis a closed enum owned by the Samocode worker:init | investigation | requirements | planning | implementation | testing | quality | pr-readiness | done. Never invent other values (deferred,planned,deployed, ...): the worker andsamocode approverefuse an overview with an unknown phase. In an interactive sessionPhasenames the next worker step; under the worker never touch it — the worker moves it from signals. Entries under## Filesand## Plansare plain- filename.md - descriptionlines, no markdown links: the worker parses## Plansto select the active plan.Commit (if sessions dir is a git repo):
cd [SESSIONS_DIR] && git add . && git commit -m "Start session: [session-name]"
Confirm to user:
Session created: [YY-MM-DD]-[session-name] Path: [full-path] Working Dir: [worktree-path or fallback] Branch: [BRANCH_NAME] IMPORTANT: This is now your active session. Remember this path for subsequent commands. Ready to work. Use /dive, /task, or /create-plan to continue.
IMPORTANT: After creating the session, keep the session path in your working memory for all subsequent session-aware commands.
Action: continue
Load and continue working in an existing session.
Steps
Resolve session location:
- If full path provided: use it
- Check project
.samocodefile forSESSIONSpath - If not found: STOP and ask user for sessions directory
Find matching sessions:
- Search sessions directory for folders matching
*$ARGUMENTS*(exclude _archive/) - Sort by modification time (most recent first)
- Search sessions directory for folders matching
Handle results:
- No matches: ERROR: "No sessions found matching '$ARGUMENTS'. Use start action to create one."
- One match: Proceed to load
- Multiple matches: List them with dates and ask user to specify
Load session:
- Read
_overview.mdfrom the session folder - Add Flow Log entry:
- [TIMESTAMP_ITERATION] Session resumed - Commit if git repo:
git add . && git commit -m "Resume session: [session-name]"
- Read
Present summary:
Session: [session-name] Path: [full-path] Working Dir: [from _overview.md] Started: [date] Recent Activity: [Last 5-10 Flow Log entries] Files: [count] [List with brief descriptions] Plans: [list if any] Linear Tasks: [list if any] --- Session loaded. Ready to continue.
IMPORTANT: After loading, keep the session path in your working memory for all subsequent session-aware commands.
Action: sync
Ensure all work from this conversation is recorded in the active session.
Steps
Check for active session:
- If no session in working memory: ERROR: "No active session. Use continue action to load one first."
Read current session state:
- Read
[SESSION_PATH]/_overview.md
- Read
Review conversation for unrecorded work:
- Code changes (files created, modified, deleted)
- Decisions made
- Problems solved
- Discoveries about the codebase
- Commits made
- Blockers/TODOs remaining
Update _overview.md:
- Add missing Flow Log entries
- Add missing Files entries
- Update other sections as needed
Create detail files if warranted:
- Only for complex topics that need more than a log entry
Commit (if git repo):
cd [SESSION_DIR] && git add . && git commit -m "Sync session: [session-name]"
Extract learnings:
- If the conversation contained friction moments (failed approaches, workarounds discovered): you MUST use "learn" skill now.
- If nothing notable was learned: skip
Report:
- "Session synced: [what was added]"
- Or: "Session already up to date."
Action: archive
Archive a session (full) or archive work within a session (partial).
Usage Patterns
archive- Archive entire active session (moves folder to _archive/)archive [session-name]- Archive entire named sessionarchive keep file1.md file2.md- Archive work files within session, keep specified filesarchive [session-path] keep file1.md- Archive work in specific session, keep files
Full Archive (no "keep" keyword)
Session Resolution
If arguments after "archive" are empty:
- Check for active session in working memory
- If no active session: ERROR: "No active session and no session name provided."
- Use active session path
If arguments provided (no "keep"):
- Search sessions directory for folders matching
*$ARGUMENTS*(exclude _archive/) - No matches: ERROR: "No sessions found matching '$ARGUMENTS'"
- One match: Confirm with user: "Archive session [name]? (y/n)"
- Multiple matches: List and ask user to specify
- Search sessions directory for folders matching
Full Archive Process
Before moving the session or removing its worktree, stop its companion HTML server.
Read the sibling companion/SKILL.md section "Required server cleanup" and follow it
even if companion is not active in this conversation. Identify ownership using the
exact absolute --directory [SESSION_PATH]/companion process argument and listener,
not just a remembered port/PID. No matching server means there is nothing to stop.
If ownership or shutdown cannot be verified, report the blocker before archiving.
Preserve companion/index.html in the archived session and report the external URL
as offline. Apply the same cleanup when explicitly closing a session without moving it;
partial work-file archive alone does not close the session.
Get session info:
- Read
[SESSION_PATH]/_overview.md - Extract Working Dir line
- Read
Create archive folder if needed:
mkdir -p [SESSIONS_DIR]/_archiveRemove worktree (if applicable):
- If Working Dir contains
/worktrees/:- Resolve
MAIN_REPOfrom.samocode(see "Repository Resolution" section) - Run worktree removal from
MAIN_REPOdirectory:cd "$MAIN_REPO" && git worktree remove [working_dir_path]
- Resolve
- If removal fails (uncommitted changes), warn user and ask to proceed or abort
- Note: Branch is preserved, only worktree removed
- If Working Dir contains
Move session folder:
mv [SESSION_PATH] [SESSIONS_DIR]/_archive/Commit changes (if git repo):
cd [SESSIONS_DIR] && git add . && git commit -m "Archive session: [session-name]"
Clear active session (if archiving active session):
- Remove from working memory
Extract learnings:
- If the conversation contained friction moments (failed approaches, workarounds discovered): you MUST use "learn" skill now.
- If nothing notable was learned: skip
Confirm to user:
Session archived: [session-name] Moved to: [archive-path] Worktree removed: [path] (branch preserved) Session closed.
Partial Archive (with "keep" keyword)
Archives completed work within a session while keeping important deliverables accessible.
Argument Parsing
- Split arguments on "keep" keyword
- Before "keep": session path (optional, defaults to active session)
- After "keep": list of files to keep in place (space-separated)
Example: archive keep competitor-analysis.md → archive active session, keep competitor-analysis.md
Partial Archive Process
Resolve session:
- If path before "keep": use it
- Otherwise: use active session from working memory
- ERROR if no session found
Get timestamp and slug:
TIMESTAMP_FOLDER=$(date '+%y-%m-%d')- Extract slug from session folder name or task name from _overview.md
- Archive folder:
[SESSION_PATH]/_archive/[YY-MM-DD]-[slug]/
Create archive subfolder:
mkdir -p [SESSION_PATH]/_archive/[YY-MM-DD]-[slug]Identify files to archive:
- All
.mdfiles in session root EXCEPT:_overview.md(always kept - session state)_qa.md(always kept if exists)_signal.json(always kept)- Files listed after "keep" keyword
- All timestamped files (pattern:
[MM-DD-HH:mm]-*.md)
- All
Move files to archive:
for file in [files_to_archive]; do mv "$file" [SESSION_PATH]/_archive/[YY-MM-DD]-[slug]/ doneUpdate _overview.md:
- Add Flow Log entry:
- [TIMESTAMP_LOG] Archived work to _archive/[YY-MM-DD]-[slug]/, kept: [kept_files] - Reset Status section for next task
- Add Flow Log entry:
Extract learnings:
- If the conversation contained friction moments (failed approaches, workarounds discovered): you MUST use "learn" skill now.
- If nothing notable was learned: skip
Report to user:
Work archived within session. Archived to: [SESSION_PATH]/_archive/[YY-MM-DD]-[slug]/ Files moved: [count] files Kept in place: [kept_files]