
Save Session
- 1 installs
- 17 repo stars
- Updated July 16, 2026
- blacktop/dotfiles
Save-session is a skill that saves AI agent session information to a file for later resumption by any AI agent.
About
Save-session saves AI agent session information so any agent can resume the work later. A developer uses it when finishing a work session and wanting to save progress, or before ending a long coding or debugging session. It writes session metadata (session ID, agent, summary) to docs/.ai/sessions.json via a bundled script and documents how to find the session ID for Claude, Codex, Gemini, Copilot, and Cursor.
- Saves AI agent session metadata to docs/.ai/sessions.json for later resumption
- Supports Claude, Codex, Gemini, Copilot, and Cursor
- Includes a Python script and per-agent session-ID discovery instructions
Save Session by the numbers
- 1 all-time installs (skills.sh)
- Ranked #2,476 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
save-session capabilities & compatibility
- Capabilities
- handoff · session save
- Use cases
- memory · project management
What save-session says it does
Save AI agent session information for later resumption.
Save session metadata to `docs/.ai/sessions.json` for future resumption by any AI agent.
Supports Claude, Codex, Gemini, Copilot, Cursor, and other AI agents.
npx skills add https://github.com/blacktop/dotfiles --skill save-sessionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 17 |
| Last updated | July 16, 2026 |
| Repository | blacktop/dotfiles ↗ |
What it does
Save AI agent session progress and metadata so any agent can resume the conversation later.
Who is it for?
Saving session progress before ending a long coding or debugging session for later resumption.
When should I use this skill?
Finishing a work session, or when the user says 'save session' or 'remember this session'.
What you get
Session metadata is written to docs/.ai/sessions.json so the work can be resumed later.
- docs/.ai/sessions.json entry
By the numbers
- Supports 5+ named AI agents
Files
Save Session
Save session metadata to docs/.ai/sessions.json for future resumption by any AI agent.
Usage
python3 ~/.agents/skills/save-session/scripts/save_session.py \
--session-id "SESSION_ID" \
--agent "claude" \
--summary "Brief description of work done" \
--repo-root "$(pwd)"For Codex, you can use automatic detection:
python3 ~/.agents/skills/save-session/scripts/save_session.py \
--session-id auto \
--agent codex \
--summary "Brief description of work done" \
--repo-root "$(pwd)"Finding Your Session ID by Agent
Claude Code
Session storage: ~/.claude/projects/<project-hash>/<SESSION_ID>.jsonl
How to find:
- Extract UUID from file paths in context (e.g., tool output paths contain the session ID)
- Use
/statuscommand to see session info - List sessions:
claude --resume(interactive picker)
Environment: CLAUDE_CONFIG_DIR changes storage location (default: ~/.claude)
Resume: claude --resume SESSION_ID or claude -r SESSION_ID
OpenAI Codex CLI
Session storage: ~/.codex/sessions/
How to find:
- Use
/statuscommand within Codex - Copy from session picker
- List files in
~/.codex/sessions/ - Or pass
--session-id auto(uses latest~/.codex/shell_snapshots/*.shfilename; verify if multiple sessions are active)
Note: Session ID is not currently exposed to the model itself (see GitHub issue #5912)
Resume: codex resume SESSION_ID
Google Gemini CLI
Session storage: ~/.gemini/tmp/<project_hash>/chats/
How to find:
- Use
gemini --list-sessionsto see all sessions with UUIDs - Sessions are project-specific
Resume options:
gemini --resume(latest session)gemini --resume <UUID>(specific session)gemini --resume <index>(by index number)/resumecommand within interactive mode
GitHub Copilot CLI
How to find:
- Use
/sessionor/usagecommand to display current session ID - Use
gh agent-task list(requires gh v2.80.0+) - Use
gh agent-task viewfor session details
Resume: /resume SESSION_ID or /resume last
Note: Auto-compaction maintains context across long sessions
Cursor IDE
Session storage: SQLite databases in workspace storage
- macOS:
~/Library/Application Support/Cursor/User/workspaceStorage/ - Linux:
~/.config/Cursor/User/workspaceStorage/ - Windows:
%APPDATA%\Cursor\User\workspaceStorage\
How to find: Sessions stored in .vscdb files as JSON blobs
Note: No built-in session ID. Use SpecStory extension for backup/export.
Aider
Session storage: Chat history in .aider.chat.history.md in repo root
Note: No formal session ID system. History is file-based and can be referenced by timestamp.
Session File Format
{
"sessions": [
{
"id": "uuid-session-id",
"agent": "claude",
"summary": "Implemented multi-platform CI",
"created_at": "2026-01-31T15:45:00Z",
"tags": ["ci", "rust"]
}
]
}Resuming Sessions
| Agent | Resume Command |
|---|---|
| Claude Code | claude --resume SESSION_ID |
| Codex | codex resume SESSION_ID |
| Gemini CLI | gemini --resume SESSION_ID |
| Copilot CLI | /resume SESSION_ID |
| Cursor | Restore from workspaceStorage backup |
| Aider | Reference .aider.chat.history.md |
#!/usr/bin/env python3
"""
Save AI agent session information for later resumption.
Supports Claude, Codex, Gemini, and other AI agents.
Stores session metadata in docs/.ai/sessions.json within the repository.
"""
import argparse
import json
import os
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
def load_sessions(sessions_file: Path) -> dict:
"""Load existing sessions or create empty structure."""
if sessions_file.exists():
with open(sessions_file, "r") as f:
return json.load(f)
return {"sessions": []}
def save_sessions(sessions_file: Path, data: dict) -> None:
"""Save sessions to file, creating parent directories if needed."""
sessions_file.parent.mkdir(parents=True, exist_ok=True)
with open(sessions_file, "w") as f:
json.dump(data, f, indent=2)
f.write("\n")
def add_session(
sessions_file: Path,
session_id: str,
agent: str,
summary: str,
tags: Optional[list[str]] = None,
) -> None:
"""Add a new session to the sessions file."""
data = load_sessions(sessions_file)
# Check if session already exists
for session in data["sessions"]:
if session["id"] == session_id:
# Update existing session
session["summary"] = summary
session["updated_at"] = datetime.now(timezone.utc).isoformat()
if tags:
session["tags"] = tags
print(f"Updated existing session: {session_id}")
save_sessions(sessions_file, data)
return
# Add new session
new_session = {
"id": session_id,
"agent": agent,
"summary": summary,
"created_at": datetime.now(timezone.utc).isoformat(),
}
if tags:
new_session["tags"] = tags
data["sessions"].append(new_session)
save_sessions(sessions_file, data)
print(f"Saved session: {session_id}")
def resolve_session_id(session_id: str, agent: str) -> str:
"""Resolve auto session IDs for supported agents."""
if session_id != "auto":
return session_id
if agent != "codex":
raise ValueError("auto session-id is only supported for agent=codex")
env_id = os.getenv("CODEX_SESSION_ID") or os.getenv("OPENAI_CODEX_SESSION_ID")
if env_id:
return env_id
snapshots_dir = Path.home() / ".codex" / "shell_snapshots"
if snapshots_dir.exists():
snapshots = sorted(
snapshots_dir.glob("*.sh"),
key=lambda path: path.stat().st_mtime,
reverse=True,
)
if snapshots:
return snapshots[0].stem
raise ValueError(
"unable to auto-detect Codex session id; run /status and pass --session-id"
)
def main():
parser = argparse.ArgumentParser(
description="Save AI agent session information for later resumption"
)
parser.add_argument(
"--session-id",
required=True,
help="Unique session identifier (UUID or agent-specific ID). Use 'auto' for Codex.",
)
parser.add_argument(
"--agent",
required=True,
choices=["claude", "codex", "gemini", "copilot", "cursor", "aider", "chatgpt", "other"],
help="AI agent type (claude, codex, gemini, copilot, cursor, aider, chatgpt, other)",
)
parser.add_argument(
"--summary",
required=True,
help="Brief description of work done in this session",
)
parser.add_argument(
"--tags",
nargs="*",
help="Optional tags for categorizing the session",
)
parser.add_argument(
"--repo-root",
default=os.getcwd(),
help="Repository root directory (default: current directory)",
)
args = parser.parse_args()
repo_root = Path(args.repo_root).resolve()
sessions_file = repo_root / "docs" / ".ai" / "sessions.json"
try:
session_id = resolve_session_id(args.session_id, args.agent)
except ValueError as exc:
print(f"Error: {exc}", file=sys.stderr)
sys.exit(2)
add_session(
sessions_file=sessions_file,
session_id=session_id,
agent=args.agent,
summary=args.summary,
tags=args.tags,
)
print(f"Sessions file: {sessions_file}")
if __name__ == "__main__":
main()