agentleFS
tsubasaogawatsubasaogawa/skills/session-stocker/SKILL.md

session-stocker

Skill0 starsChanged 32 days agoMITView on GitHub

Summarize useful knowledge from the current conversation and save it as a Markdown note in the directory configured by `config.toml` (`artifacts.directory`). Use this skill whenever the user asks to stock, archive, preserve, save, memoize, or record the current session, especially when they say phrases like `このセッションをストックして`, want a reusable note from the conversation, or ask to write a session summary into an artifacts folder.

The file

Show its rules and text

We split this skill into the rules it gives an agent

40 rules. About 0 are common, 17 are distinctive, and 23 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈17

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 23

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when the user wants to preserve the current session as a note, especially if they want the result written to disk for later …

    line 18
  2. Very specific:

    If that file doesn't exist, stop and tell the user to create it (they can copy config.toml.template from the skill directory to …

    line 38
  3. Very specific:

    Leave any other {{...}} untouched.

    line 65
  4. Distinctive:

    If the template file can't be read (key set but file missing), tell the user and stop — don't silently fall back to the built-in layout.

    line 67
  5. Very specific:

    When plain mode is on, the file uses ## 回答内容 instead of ## 会話内容 (see Output requirements and Writing guidance) — the two never appear …

    line 76
  6. Distinctive:

    Create one Markdown file at:

    line 97
  7. Distinctive:

    If the session includes one or more relevant URLs, append this optional section last:

    line 135
  8. Distinctive:

    Create a short summary phrase from the conversation.

    line 146
  9. Very specific:

    Remove or replace characters that are unsafe in filenames, such as /, \\, :, *, ?, ", <, >, and |.

    line 163
  10. Distinctive:

    Keep the summary readable after sanitizing.

    line 165
  11. Very specific:

    If a file with the same name already exists, append -2, -3, and so on instead of overwriting it.

    line 167
  12. Very specific:

    Write it as <vendor>.<model-name>, where <vendor> is the lowercase provider name and <model-name> is the model's own identifier:

    line 175
  13. Very specific:

    Use the plain model name. Strip deployment/region prefixes (us.anthropic.…) and context-window or variant suffixes such as [1m].

    line 185
  14. Very specific:

    Keep the API-style dated model ID if that's the identifier you know yourself by (e.g.

    line 186
  15. Very specific:

    If you genuinely cannot determine your own model name, write model: unknown rather than guessing.

    line 187
  16. Distinctive:

    Do not add other frontmatter keys unless the user asks for them.

    line 188
  17. Distinctive:

    Write a short overview of what the session accomplished.

    line 192
  18. Distinctive:

    Use the actual message text the user and assistant exchanged, not a paraphrase.

    line 199
  19. Distinctive:

    Leave out tool-call/tool-result noise (function calls, raw command output, intermediate tool payloads) — keep only what the user and the …

    line 200
  20. Distinctive:

    If the session is extremely long, it's fine to include the whole thing.

    line 201
  21. Very specific:

    When simplify mode is on (--simplify), write a condensed summary of the exchange instead — cover the key turns, decisions, and outcomes, …

    line 202
  22. Very specific:

    Use the actual assistant message text, verbatim — do not summarize or paraphrase, same as 会話内容.

    line 208
  23. Very specific:

    Leave out tool-call/tool-result noise, raw command output, and system-reminder content, same exclusion rule as 会話内容.

    line 209
  24. Very specific:

    When simplify mode is on (--simplify), write a condensed summary of the assistant's output instead — cover the key points and outcomes, but …

    line 211
  25. Distinctive:

    Only write this section when the user has confirmed they want it (see Execution steps) — otherwise leave it out entirely.

    line 223
  26. Distinctive:

    Do not include file paths, command names, tool names, issue or PR numbers, or any other non-URL references.

    line 229
  27. Very specific:

    If there are no relevant URLs, omit the entire 参考情報 section.

    line 231
  28. Distinctive:

    When that happens, decide the link style by whether the stock is Obsidian-managed:

    line 237
  29. Very specific:

    Not Obsidian-managed (not a Git repo, or no .obsidian at the root): use a normal Markdown relative link, Note Title.

    line 245
  30. Very specific:

    Only relevant when use_obsidian_cli = true, or when a vault is named explicitly.

    line 251
  31. Very specific:

    Keep the temp body file around until the session is finished with the note.

    line 267
  32. Very specific:

    Not in plain mode: the transcript (会話内容).

    line 281
  33. Distinctive:

    Not in simplify mode (default): write that content verbatim, turn-by-turn.

    line 283
  34. Very specific:

    Read ~/.config/session-stocker/config.toml and resolve artifacts.directory, use_obsidian_cli, and template.

    line 286
  35. Very specific:

    If template is set, read the template file: with use_obsidian_cli = true or a vault named explicitly, run python3 …

    line 287
  36. Distinctive:

    Check whether the user's request or slash-command ARGUMENTS name an Obsidian vault to save into.

    line 288
  37. Very specific:

    No vault named, use_obsidian_cli = false: ensure the artifacts directory exists (create it if necessary) and write the file there using the …

    line 290
  38. Very specific:

    No vault named, use_obsidian_cli = true: write the body to a temp file and run scripts/obsidian_stock.py create as described above — it …

    line 291
  39. Distinctive:

    Before saving, check that:

    line 297
  40. Very specific:

    when 参考情報 is present, it contains URLs only

    line 308

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Session Stock

Turn the current session into a reusable Markdown artifact and save it to the directory configured by config.toml.

Goal

Capture the conversation in a form the user can revisit later. Preserve the actual exchange verbatim rather than compressing it into a summary — durable takeaways (知見) are an optional add-on, not the primary content. Pass --simplify in the invoking ARGUMENTS to condense the transcript into a summary instead; this is off by default (see Simplify mode).

When to use this skill

Use this skill when the user wants to preserve the current session as a note, especially if they want the result written to disk for later reference.

Typical triggers include:

  • このセッションをストックして
  • この会話を残して
  • 今回の内容を artifacts に保存して
  • セッションの知見をメモ化して

Configuration

The config file always lives at ~/.config/session-stocker/config.toml, regardless of where this skill itself is installed:

[artifacts]
directory = "/path/to/your/artifacts"
use_obsidian_cli = false
vault_name = ""
template = ""

If that file doesn't exist, stop and tell the user to create it (they can copy config.toml.template from the skill directory to ~/.config/session-stocker/config.toml and fill in artifacts.directory) rather than guessing a directory or writing anywhere else.

use_obsidian_cli decides how the note is written, and also changes what artifacts.directory means. The content rules are identical either way. Treat a missing key as false.

  • false — artifacts.directory is an absolute filesystem path. Write the file straight there with your normal file-writing tool.
  • true — artifacts.directory is a folder relative to the vault root (leave it empty to save at the vault root), and the write goes through the bundled script as described in Stocking into an Obsidian vault. Use this when the note belongs in a vault whose filesystem location you should not have to know or hardcode: the script resolves the vault by name, so the same config works from WSL against a Windows-side vault.

vault_name names which vault to save into when use_obsidian_cli = true. Leave it empty to use whichever vault Obsidian currently has focused — the bundled script asks the CLI for the active vault when no name is configured, which is the one case that needs Obsidian to be running. Set it explicitly when you want a specific vault regardless of what's currently open in Obsidian, or when Obsidian may be closed.

template optionally points at a Markdown file the note is rendered from instead of the built-in layout (see Template mode). It is resolved the same way as artifacts.directory: an absolute filesystem path (~ allowed) when use_obsidian_cli = false, a vault-relative path when use_obsidian_cli = true or a vault is named explicitly. Treat a missing or empty key as "no template".

Template mode

Template mode is on whenever artifacts.template is set. The note is then produced by taking the template file verbatim and replacing the placeholders below — nothing else in the template is edited, reordered, or removed, and the built-in layout from Output requirements does not apply. The filename rule is unchanged.

PlaceholderReplaced with
{{title}}the session summary (same text as the title part of the filename)
{{date}}current local date, YYYY-MM-DD
{{time}}current local time, HH:mm
{{model}}<vendor>.<model-name> (see frontmatter)
{{summary}}the body of 概要
{{content}}the body of 会話内容 — or 回答内容 in plain mode; --plain / --simplify apply exactly as without a template
{{insights}}the body of 知見; an empty string on the first save
{{references}}the 参考情報 URL bullets; an empty string when there are none
  • Replace a placeholder with the body only — the template owns the headings, so don't emit ## 概要 and friends yourself.
  • Leave any other {{...}} untouched; only the placeholders in the table are yours. Templater's <% %> syntax is not affected either.
  • The template is responsible for the frontmatter. Recommend model: {{model}} there if the user asks how to write one, but never add keys or sections the template doesn't contain.
  • If the template file can't be read (key set but file missing), tell the user and stop — don't silently fall back to the built-in layout.
  • Adding 知見 later: if the template contains {{insights}}, re-render the whole template with it filled in and overwrite the saved note. If it doesn't, insert ## 知見 right after the content section as in the built-in layout.

Plain mode

By default, the stock target is the full conversation (会話内容, verbatim turns from both the user and the assistant). Plain mode narrows that down to assistant output only — every assistant utterance in the session, in order, with user turns left out entirely.

Plain mode is on only when the slash-command ARGUMENTS that invoked this skill literally contain the bare flag --plain (e.g. /session-stocker --plain). It takes no value — --plain alone turns it on, and its absence leaves it off. A natural-language request like「plain で保存して」does not trigger it — only the explicit ARGUMENTS flag does. This check is independent of the vault-name override described below; both can apply at once.

When plain mode is on, the file uses ## 回答内容 instead of ## 会話内容 (see Output requirements and Writing guidance) — the two never appear together in the same note.

Simplify mode

By default, 会話内容 (or 回答内容 in plain mode) is a verbatim, turn-by-turn transcript. Simplify mode replaces that with a condensed summary of what was discussed/done instead — still faithful to what happened, but not word-for-word.

Simplify mode is on only when the slash-command ARGUMENTS that invoked this skill literally contain the bare flag --simplify (e.g. /session-stocker --simplify). It takes no value — --simplify alone turns it on, and its absence leaves it off. A natural-language request like「内容を要約して保存して」does not trigger it — only the explicit ARGUMENTS flag does. Without the flag the transcript stays verbatim, matching the skill's existing behavior.

Simplify mode is independent of Plain mode — the two combine freely:

--plain--simplifySectionContent
absent (default)absent (default)会話内容verbatim, both parties
absentpresent会話内容summarized, both parties
presentabsent回答内容verbatim, assistant only
presentpresent回答内容summarized, assistant only

Output requirements

The layout below applies when no template is configured. In template mode the template decides the layout.

Create one Markdown file at:

<artifacts-directory>/<YYYYMMDD>_<HHMM>_<session-summary>.md

Resolve <artifacts-directory> from ~/.config/session-stocker/config.toml using artifacts.directory (see Configuration above).

The file must always start with a YAML frontmatter block, followed by these sections in this order:

---
model: <vendor>.<model-name>
---
# <session-summary>

## 概要

## 会話内容

In plain mode (see Plain mode), use ## 回答内容 in place of ## 会話内容 — never both:

---
model: <vendor>.<model-name>
---
# <session-summary>

## 概要

## 回答内容

知見 is optional. Only add it after saving, once the user has confirmed they want it (see Execution steps). When present, it goes right after 会話内容 (or 回答内容 in plain mode):

## 知見

If the session includes one or more relevant URLs, append this optional section last:

## 参考情報
- https://example.com/reference

Writing guidance

1. Decide the session summary

Create a short summary phrase from the conversation.

Good summaries are:

  • short and specific
  • understandable without the full chat log
  • suitable for a filename

Examples:

  • Terraform module 分割方針
  • Python 集計スクリプト改善
  • GitHub Actions 失敗原因調査

2. Build a safe filename

  • Prefix the filename with the current date and time in YYYYMMDD_HHMM format (24-hour clock, local time).
  • Convert the summary into a filename-safe form.
  • Spaces are allowed in the title portion — do not replace them with - or _.
  • Remove or replace characters that are unsafe in filenames, such as /, \\, :, *, ?, ", <, >, and |.
  • With use_obsidian_cli = true, also drop #, ^, [, and ] — Obsidian rejects them in note names.
  • Keep the summary readable after sanitizing.

If a file with the same name already exists, append -2, -3, and so on instead of overwriting it.

3. Write the content

frontmatter

The note opens with a YAML frontmatter block whose only required key is model: the AI model that wrote the note — that is, the model running this skill right now, not a model that merely came up in the conversation.

Write it as <vendor>.<model-name>, where <vendor> is the lowercase provider name and <model-name> is the model's own identifier:

---
model: anthropic.claude-opus-5
---

Examples: anthropic.claude-opus-5, anthropic.claude-sonnet-5, openai.codex-gpt-5.6-terra.

  • Use the plain model name. Strip deployment/region prefixes (us.anthropic.…) and context-window or variant suffixes such as [1m].
  • Keep the API-style dated model ID if that's the identifier you know yourself by (e.g. anthropic.claude-haiku-4-5-20251001).
  • If you genuinely cannot determine your own model name, write model: unknown rather than guessing.
  • Do not add other frontmatter keys unless the user asks for them.

概要

Write a short overview of what the session accomplished. Keep it compact and outcome-oriented.

会話内容

This is the core of the artifact: a verbatim, turn-by-turn transcript of what the user and the assistant actually said, in order. Do not summarize or condense it — the whole point of this section is to preserve the conversation as it happened, not a distilled version of it.

  • Render each turn as a **User:** or **Assistant:** block followed by that turn's text, in the order the turns occurred.
  • Use the actual message text the user and assistant exchanged, not a paraphrase.
  • Leave out tool-call/tool-result noise (function calls, raw command output, intermediate tool payloads) — keep only what the user and the assistant actually said to each other. Local-command output and system-reminder tags are not part of the conversation and should also be left out.
  • If the session is extremely long, it's fine to include the whole thing; do not truncate for length unless the user asks you to.
  • When simplify mode is on (--simplify), write a condensed summary of the exchange instead — cover the key turns, decisions, and outcomes, but do not preserve exact wording. This does not apply when simplify is off (default), where the verbatim rule above still governs.

回答内容 (plain mode only)

Used instead of 会話内容 when plain mode is on. Contains every assistant utterance from the session, in order, with user turns left out entirely.

  • Use the actual assistant message text, verbatim — do not summarize or paraphrase, same as 会話内容.
  • Leave out tool-call/tool-result noise, raw command output, and system-reminder content, same exclusion rule as 会話内容.
  • Separate consecutive assistant utterances so the boundaries stay legible when read back — a **Assistant:** label per turn or a --- divider both work. Don't use **User:** labels; there's nothing to attribute to the user in this section.
  • When simplify mode is on (--simplify), write a condensed summary of the assistant's output instead — cover the key points and outcomes, but do not preserve exact wording. This does not apply when simplify is off (default), where the verbatim rule above still governs.

知見

Optional. List the important learnings, decisions, trade-offs, or implementation notes that would help someone reuse the result later. Prefer bullets when there are multiple items.

Include:

  • conclusions that were reached
  • constraints or assumptions that mattered
  • patterns worth repeating
  • pitfalls or caveats discovered during the session

Only write this section when the user has confirmed they want it (see Execution steps) — otherwise leave it out entirely.

参考情報

Record only relevant URLs from the session that may be useful later.

Do not include file paths, command names, tool names, issue or PR numbers, or any other non-URL references.

If there are no relevant URLs, omit the entire 参考情報 section.

4. Linking to other notes (Obsidian-aware)

This skill doesn't go looking for related notes to link on its own — this rule only matters if a section ends up referencing another note that already lives in the same stock directory (for example, if the user asks you to link a related past note, or 知見 naturally calls one out).

When that happens, decide the link style by whether the stock is Obsidian-managed:

  • use_obsidian_cli = true already answers this — the stock is Obsidian-managed, no further detection needed.
  • Otherwise, resolve the Git repository root for artifacts.directory (e.g. git -C <artifacts-directory> rev-parse --show-toplevel) and check whether a .obsidian directory exists directly under that root. If it does, the stock is Obsidian-managed.

Then pick the syntax:

  • Obsidian-managed: use Obsidian's wiki link syntax, [[Note Title]] (no .md extension; use [[Note Title|Display Text]] if you need an alias).
  • Not Obsidian-managed (not a Git repo, or no .obsidian at the root): use a normal Markdown relative link, [Note Title](relative/path.md).

This only governs links between notes in the stock. 参考情報 stays URL-only regardless of this detection.

Stocking into an Obsidian vault

Only relevant when use_obsidian_cli = true, or when a vault is named explicitly. See rules/obsidian.md for the CLI's general syntax if you need ad-hoc commands.

Never write the note with obsidian create yourself. The CLI expands \n and \t inside content= and offers no way to escape a backslash, so a transcript containing Windows paths, regexes, or code with \n in a string would be silently corrupted — exactly the fidelity this skill exists to protect. Worse, a multi-kilobyte content= argument has been observed to crash Obsidian's main process outright. Use the bundled script instead: it resolves the vault's filesystem path and writes the file directly, so the body never passes through the CLI and nothing is escaped:

python3 <skill-dir>/scripts/obsidian_stock.py create \
  --title "<session summary>" \
  --body /tmp/session-stock-body.md

Write the Markdown body (everything from the --- frontmatter block down) to a temp file first, then pass it with --body. The script writes the bytes as-is, so the frontmatter arrives intact. The script resolves the vault (from vault_name, or the currently focused vault if that's empty), treats artifacts.directory as the vault-relative folder, adds the YYYYMMDD_HHMM prefix, sanitizes the title, picks a collision-free -2/-3 name, verifies the file on disk byte for byte, and prints the vault name and note path it used. Report that path to the user.

Obsidian does not need to be running. The script reads the vault registry from obsidian.json when the CLI does not answer, and a running Obsidian is asked to open the new note only as a best-effort nicety — if it is closed, its file watcher indexes the note at next start. The one exception is an unnamed vault: resolving "whichever vault is currently focused" requires a running Obsidian.

Explicit vault override: if the user's request or slash-command ARGUMENTS name an Obsidian vault to save into (e.g. "Work vault に保存して"), prioritize that vault for this run by passing --vault "<name>" — same pattern as semantic-commit-helper prioritizing a language named in ARGUMENTS. This overrides vault_name (and the fallback to whichever vault is currently focused), and it applies even if use_obsidian_cli is false: naming a vault is itself a signal the user wants this note saved into Obsidian. The folder still comes from artifacts.directory as a vault-relative path (empty means vault root).

Keep the temp body file around until the session is finished with the note. To append 知見 later, edit that same local file and push the whole thing back:

python3 <skill-dir>/scripts/obsidian_stock.py overwrite \
  --path "<vault-relative path printed by create>" \
  --body /tmp/session-stock-body.md

If the script fails — vault_name not among the known vaults, the vault path not readable, or no vault could be detected as active — surface its error message and stop. Don't fall back to writing the file somewhere else: the user pointed the config at a vault on purpose, and a note stashed in an unexpected directory is worse than no note.

Execution steps

  1. Check whether the slash-command ARGUMENTS that invoked this skill literally contain the bare flag --plain. If so, this run is in plain mode. Separately, check whether they literally contain the bare flag --simplify. If so, this run is in simplify mode; otherwise simplify is off (default).
  2. Review the current conversation and reconstruct the content section:
    • Not in plain mode: the transcript (会話内容).
    • In plain mode: every assistant utterance, in order, with user turns left out (回答内容).
    • Not in simplify mode (default): write that content verbatim, turn-by-turn.
    • In simplify mode: write that content as a condensed summary instead of a verbatim transcript. Generate the session summary either way, and build the model frontmatter from your own model name (see frontmatter).
  3. Read ~/.config/session-stocker/config.toml and resolve artifacts.directory, use_obsidian_cli, and template. Determine the current local date and time (YYYYMMDD_HHMM) for the filename.
  4. If template is set, read the template file: with use_obsidian_cli = true or a vault named explicitly, run python3 <skill-dir>/scripts/obsidian_stock.py template [--vault "<name>"] and read the local path it prints; otherwise read the absolute path directly. Render the note by replacing the placeholders (Template mode) instead of building the built-in layout.
  5. Check whether the user's request or slash-command ARGUMENTS name an Obsidian vault to save into. Save the note:
    • A vault was named explicitly: write the body to a temp file and run scripts/obsidian_stock.py create --vault "<name>" as described above, regardless of use_obsidian_cli.
    • No vault named, use_obsidian_cli = false: ensure the artifacts directory exists (create it if necessary) and write the file there using the required naming rule.
    • No vault named, use_obsidian_cli = true: write the body to a temp file and run scripts/obsidian_stock.py create as described above — it handles the naming rule and the directory itself.
  6. Tell the user the saved path and briefly summarize what was captured.
  7. Ask the user whether they want to add a 知見 section, e.g. 「知見を追加しますか?」. If they say yes, extract the durable learnings and add the 知見 section to the already-saved note (right after 会話内容 or 回答内容, before 参考情報 if present) — editing the file directly, or via scripts/obsidian_stock.py overwrite when the Obsidian CLI is in use. Keep the frontmatter block untouched when you push the note back. If they decline or don't respond, leave the note as is.

Quality bar

Before saving, check that:

  • the file is actually written to disk (with use_obsidian_cli = true, the script's own round-trip check covers this — if it reports a mismatch, tell the user instead of retrying blindly)
  • the note body was never passed to the obsidian CLI as an argument
  • the filename matches the required pattern
  • the note starts with a YAML frontmatter block carrying model: <vendor>.<model-name>, naming the model that actually wrote the note
  • exactly one of 会話内容 (normal mode) or 回答内容 (plain mode) is present, matching whether --plain was in the invoking ARGUMENTS — never both
  • the 会話内容 section is a verbatim transcript of the actual exchange, not a summary or paraphrase — unless --simplify was in the invoking ARGUMENTS, in which case it's a condensed summary instead
  • the 回答内容 section, when present, contains only assistant utterances (no user turns), verbatim — unless --simplify was in the invoking ARGUMENTS, in which case it's a condensed summary instead
  • tool-call noise, raw command output, and system-reminder content are excluded from 会話内容 / 回答内容
  • the 知見 section is only present if the user explicitly asked for it, and if so, contains real takeaways rather than a repeat of the transcript
  • the 参考情報 section appears only when relevant URLs exist
  • when 参考情報 is present, it contains URLs only
  • any link to another note in the stock directory follows the Obsidian-detection rule (wiki link vs. Markdown link), not a mix of both
  • in template mode: every placeholder from the table is replaced, no other text in the template was changed, and no built-in headings were added on top of the template

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.