本文へ移動
cccskills
無料GitHub で公開

session-save

Save current Codex session to 2ndBrain vault with frontmatter, executive brief, and full transcript

インストール方法を見る

含まれるファイル(2)

  • SKILL.md7.5 KB
  • agents/openai.yaml43 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

session-save

Use this skill when the user asks to run the migrated command session-save or invokes $session-save.

Command Template

Save Session to 2ndBrain

Saves the current Codex session as a note in ~/2ndBrain/Codex-sessions/<year>/.

The note structure:

  1. YAML frontmatter — date, hostname, session name, cwd, git branch, token counts
  2. Executive brief — 3–5 bullet summary of what was done, key decisions, and open items
  3. --- separator
  4. Full session transcript — formatted as **User**: ... / **Codex**: ... blocks with tool calls noted inline

Step 1: Gather Environment Metadata

session_date=$(date +%Y-%m-%d)
session_time=$(date +%H:%M:%S)
session_year=$(date +%Y)
host=$(hostname -s)
cwd=$(pwd)
echo "date=${session_date} time=${session_time} host=${host} cwd=${cwd} year=${session_year}"

Step 2: Find Current Session File

encoded_cwd=$(pwd | sed 's|/|-|g')
project_dir="$HOME/.Codex/projects/${encoded_cwd}"
session_file=$(ls -t "${project_dir}"/*.jsonl 2>/dev/null | head -1)
if [ -z "$session_file" ]; then
  echo "ERROR: No session file found in ${project_dir}" >&2
  exit 1
fi
echo "session_file=${session_file}"

Step 3: Parse Session File

Run this Python script to extract all session data:

python3 << 'PYEOF'
import json, sys, os, subprocess, glob

cwd = subprocess.check_output(['pwd']).decode().strip()
encoded = cwd.replace('/', '-')
home = os.path.expanduser('~')
project_dir = f"{home}/.Codex/projects/{encoded}"
files = sorted(glob.glob(f"{project_dir}/*.jsonl"), key=os.path.getmtime, reverse=True)
session_file = files[0] if files else ''

if not session_file:
    print(json.dumps({'error': 'No session file found'}))
    sys.exit(1)

messages = []
total_output_tokens = 0
last_input_tokens = 0
session_id = None
ai_title = None
git_branch = None
session_cwd = None

with open(session_file) as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        try:
            entry = json.loads(line)
        except json.JSONDecodeError:
            continue

        if not session_id:
            session_id = entry.get('sessionId')
        if not git_branch and 'gitBranch' in entry:
            git_branch = entry['gitBranch']
        if not session_cwd and 'cwd' in entry:
            session_cwd = entry['cwd']

        # Grab latest ai-title
        if entry.get('type') == 'ai-title':
            ai_title = entry.get('aiTitle')
            continue

        entry_type = entry.get('type')
        if entry_type not in ('user', 'assistant'):
            continue

        # Skip meta/system user turns (isMeta = true with no real content)
        is_meta = entry.get('isMeta', False)
        msg = entry.get('message', {})
        if not isinstance(msg, dict):
            continue

        role = msg.get('role', entry_type)
        raw_content = msg.get('content', '')

        # Parse content blocks into text
        parts = []
        if isinstance(raw_content, list):
            for block in raw_content:
                if not isinstance(block, dict):
                    continue
                btype = block.get('type')
                if btype == 'text':
                    text = block.get('text', '').strip()
                    if text:
                        parts.append(text)
                elif btype == 'tool_use':
                    name = block.get('name', 'unknown')
                    inp = block.get('input', {})
                    # Summarize key input fields
                    summary_keys = ['command', 'path', 'file_path', 'query', 'skill', 'description']
                    detail = next((str(inp[k])[:120] for k in summary_keys if k in inp), '')
                    if detail:
                        parts.append(f'[→ {name}: {detail}]')
                    else:
                        parts.append(f'[→ {name}]')
                elif btype == 'tool_result':
                    pass  # omit tool results from transcript
        elif isinstance(raw_content, str):
            if raw_content.strip():
                parts.append(raw_content.strip())

        content = '\n'.join(parts).strip()
        if not content:
            continue

        # Skip purely-meta user turns (no actual user text, just system context)
        if is_meta and role == 'user' and not any(p for p in parts if not p.startswith('[')):
            continue

        messages.append({'role': role, 'content': content})

        # Token accounting
        usage = msg.get('usage', {})
        out = usage.get('output_tokens', 0)
        inp_total = (usage.get('input_tokens', 0)
                     + usage.get('cache_creation_input_tokens', 0)
                     + usage.get('cache_read_input_tokens', 0))
        if out:
            total_output_tokens += out
        if inp_total:
            last_input_tokens = inp_total

print(json.dumps({
    'session_id': session_id,
    'ai_title': ai_title,
    'git_branch': git_branch,
    'session_cwd': session_cwd,
    'total_output_tokens': total_output_tokens,
    'last_input_tokens': last_input_tokens,
    'total_tokens': last_input_tokens + total_output_tokens,
    'message_count': len(messages),
    'messages': messages,
}, ensure_ascii=False))
PYEOF

Capture the JSON output from this script. If it contains "error", report the error and stop.

Step 4: Generate Executive Brief

Read the messages array from the parsed JSON. Based on the full conversation content, write a concise executive brief:

  • 3–5 bullet points covering: what was investigated/built, key decisions made, commands run or files changed, and any open items or next steps
  • Tone: factual, past-tense, no filler ("we looked at", "the user asked" — just state what happened)
  • Each bullet should be one sentence

Example format:

- Audited the obsidian-skills plugin and three work commands that reference ~/2ndBrain/daily-notes.
- Discovered the JSONL session format includes an ai-title field, session_id, cwd, gitBranch, and per-message usage stats.
- Designed and wrote the /session-save command to ~/2ndBrain/Codex-sessions/.

Step 5: Determine Output Path

Use the ai_title from Step 3 (or "Untitled Session" if absent). Sanitize it for use as a filename: replace /, :, | with -; collapse spaces.

vault=~/2ndBrain
out_dir="${vault}/Codex-sessions/${session_year}"
filename="${session_date} ${ai_title}.md"
out_path="${out_dir}/${filename}"

Ensure the directory exists:

mkdir -p "${out_dir}"

Step 6: Format and Write the Note

Use the Write tool to create ${out_path} with this structure:

---
date: <YYYY-MM-DD>
time: <HH:MM:SS>
hostname: <host>
session: <ai_title>
session_id: <session_id>
cwd: <session_cwd>
branch: <git_branch>
tokens:
  output: <total_output_tokens>
  context: <last_input_tokens>
  total: <total_tokens>
messages: <message_count>
tags:
  - Codex-session
---

## Executive Brief

<bullet points from Step 4>

---

## Session Transcript

<for each message in order:>

**User**

<content>

---

**Codex**

<content>

---

<repeat for all messages>

Separate each message with ---. Keep the full content of each message — do not truncate.

Step 7: Report

Output a one-line confirmation:

Session saved: ~/2ndBrain/Codex-sessions/<year>/<filename>
Tokens: <last_input_tokens> context / <total_output_tokens> output / <total_tokens> total | Messages: <message_count>

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

2ndbrain

無料

Quick-save the last assistant response as a verbatim note in the 2ndBrain Obsidian vault (~/2ndBrain/quick-notes/<year>/). Use when the user asks to quick-save/save the last response to 2ndBrain, or invokes $2ndbrain or /skill:2ndbrain.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

Write commit messages under the agent-commits convention - a Conventional Commits fork with no chore catch-all, intent-only type tokens, facts in trailers, and legally-grounded AI provenance (Assisted-by, never Co-authored-by). Use when composing a commit in a repo whose commitlint.config.js extends agent-commits, when deciding between feat/fix/refactor/perf, or when recording AI participation.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

Coordinate multi-agent work through durable artifacts in git instead of chat. Use this whenever a task involves sending a message to another agent, agent mailboxes or handoffs, claiming work from a shared queue, notifying another agent or crew (OpenClaw, Grok Bot, Claude Code, Codex, Gas Town/Gas City workers) that work is ready, or whenever the user mentions the artifact bus, message bus, agent mail, beads mail, doorbells, or pings between agents — even if they don't say "bus" explicitly.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

aven

無料

Use aven to find tasks, update status, and leave durable handoff context.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

boris

無料

Codex workflow tips from Boris Cherny (creator of Codex) and the Codex team. Use when: setting up Codex, optimizing workflows, running parallel sessions, configuring AGENTS.md, using skills/commands, subagents, hooks, MCP integrations, or learning best practices. Covers: git worktrees, plan mode, verification, permissions, Slack MCP, BigQuery, prompting tips, plugins, custom agents, sandboxing, keybindings, status lines, output styles, customization, /simplify for code quality, /batch for parallel code migrations, /loop for scheduled tasks, code review agents, /btw for mid-task questions, /effort max reasoning, remote control sessions, voice mode, setup scripts, session naming, /color, PostCompact hook, auto mode, /schedule cloud jobs, iMessage plugin, auto-memory, and auto-dream, mobile app, session teleporting, Cowork Dispatch, Chrome extension, Desktop app, /branch forking, --bare SDK startup, --add-dir multi-repo, --agent custom agents, /voice input.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

boris

無料

Claude Code workflow tips from Boris Cherny (creator of Claude Code) and the Claude Code team. Use when: setting up Claude Code, optimizing workflows, running parallel sessions, configuring CLAUDE.md, using skills/commands, subagents, hooks, MCP integrations, or learning best practices. Covers: git worktrees, plan mode, verification, permissions, Slack MCP, BigQuery, prompting tips, plugins, custom agents, sandboxing, keybindings, status lines, output styles, customization, /simplify for code quality, /batch for parallel code migrations, /loop for scheduled tasks, code review agents, /btw for mid-task questions, /effort max reasoning, remote control sessions, voice mode, setup scripts, session naming, /color, PostCompact hook, auto mode, /schedule cloud jobs, iMessage plugin, auto-memory, and auto-dream, mobile app, session teleporting, Cowork Dispatch, Chrome extension, Desktop app, /branch forking, --bare SDK startup, --add-dir multi-repo, --agent custom agents, /voice input.

日本語の概要は準備中です。原文の説明を表示しています。

phatblat/dotfiles122026年10月11日 更新

phatblat のスキルをすべて見る

このスキルの問題を報告する