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.
In this repository13 other files it gives its agents.
- ai-credit-efficient-reviewSkill
- branch-tldrSkill
- drafting-tweet-from-todaySkill
- finding-unused-customizationsSkill
- hacker-news-digest-jaSkill
- japanese-tech-writingSkill
- natural-japaneseSkill
- pr-branch-composition-checkSkill
- prompt-feedback-skillSkill
- resume-improverSkill
- semantic-commit-helperSkill
- syncing-forked-skillsSkill
- tf-destroy-plan-inverterSkill
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
- Distinctive: line 18
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 …
- Very specific: line 38
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 …
- Very specific: line 65
Leave any other {{...}} untouched.
- Distinctive: line 67
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.
- Very specific: line 76
When plain mode is on, the file uses ## 回答内容 instead of ## 会話内容 (see Output requirements and Writing guidance) — the two never appear …
- Distinctive: line 97
Create one Markdown file at:
- Distinctive: line 135
If the session includes one or more relevant URLs, append this optional section last:
- Distinctive: line 146
Create a short summary phrase from the conversation.
- Very specific: line 163
Remove or replace characters that are unsafe in filenames, such as /, \\, :, *, ?, ", <, >, and |.
- Distinctive: line 165
Keep the summary readable after sanitizing.
- Very specific: line 167
If a file with the same name already exists, append -2, -3, and so on instead of overwriting it.
- Very specific: line 175
Write it as <vendor>.<model-name>, where <vendor> is the lowercase provider name and <model-name> is the model's own identifier:
- Very specific: line 185
Use the plain model name. Strip deployment/region prefixes (us.anthropic.…) and context-window or variant suffixes such as [1m].
- Very specific: line 186
Keep the API-style dated model ID if that's the identifier you know yourself by (e.g.
- Very specific: line 187
If you genuinely cannot determine your own model name, write model: unknown rather than guessing.
- Distinctive: line 188
Do not add other frontmatter keys unless the user asks for them.
- Distinctive: line 192
Write a short overview of what the session accomplished.
- Distinctive: line 199
Use the actual message text the user and assistant exchanged, not a paraphrase.
- Distinctive: line 200
Leave out tool-call/tool-result noise (function calls, raw command output, intermediate tool payloads) — keep only what the user and the …
- Distinctive: line 201
If the session is extremely long, it's fine to include the whole thing.
- Very specific: line 202
When simplify mode is on (--simplify), write a condensed summary of the exchange instead — cover the key turns, decisions, and outcomes, …
- Very specific: line 208
Use the actual assistant message text, verbatim — do not summarize or paraphrase, same as 会話内容.
- Very specific: line 209
Leave out tool-call/tool-result noise, raw command output, and system-reminder content, same exclusion rule as 会話内容.
- Very specific: line 211
When simplify mode is on (--simplify), write a condensed summary of the assistant's output instead — cover the key points and outcomes, but …
- Distinctive: line 223
Only write this section when the user has confirmed they want it (see Execution steps) — otherwise leave it out entirely.
- Distinctive: line 229
Do not include file paths, command names, tool names, issue or PR numbers, or any other non-URL references.
- Very specific: line 231
If there are no relevant URLs, omit the entire 参考情報 section.
- Distinctive: line 237
When that happens, decide the link style by whether the stock is Obsidian-managed:
- Very specific: line 245
Not Obsidian-managed (not a Git repo, or no .obsidian at the root): use a normal Markdown relative link, Note Title.
- Very specific: line 251
Only relevant when use_obsidian_cli = true, or when a vault is named explicitly.
- Very specific: line 267
Keep the temp body file around until the session is finished with the note.
- Very specific: line 281
Not in plain mode: the transcript (会話内容).
- Distinctive: line 283
Not in simplify mode (default): write that content verbatim, turn-by-turn.
- Very specific: line 286
Read ~/.config/session-stocker/config.toml and resolve artifacts.directory, use_obsidian_cli, and template.
- Very specific: line 287
If template is set, read the template file: with use_obsidian_cli = true or a vault named explicitly, run python3 …
- Distinctive: line 288
Check whether the user's request or slash-command ARGUMENTS name an Obsidian vault to save into.
- Very specific: line 290
No vault named, use_obsidian_cli = false: ensure the artifacts directory exists (create it if necessary) and write the file there using the …
- Very specific: line 291
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 …
- Distinctive: line 297
Before saving, check that:
- Very specific: line 308
when 参考情報 is present, it contains URLs only
≈ “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.
Files
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.directoryis an absolute filesystem path. Write the file straight there with your normal file-writing tool.true—artifacts.directoryis 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.
| Placeholder | Replaced 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 | --simplify | Section | Content |
| absent (default) | absent (default) | 会話内容 | verbatim, both parties |
| absent | present | 会話内容 | summarized, both parties |
| present | absent | 回答内容 | verbatim, assistant only |
| present | present | 回答内容 | 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/referenceWriting 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_HHMMformat (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: unknownrather 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 = truealready 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.obsidiandirectory 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.mdextension; use[[Note Title|Display Text]]if you need an alias). - Not Obsidian-managed (not a Git repo, or no
.obsidianat 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.mdWrite 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.mdIf 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
- 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). - 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
modelfrontmatter from your own model name (see frontmatter).
- Not in plain mode: the transcript (
- Read
~/.config/session-stocker/config.tomland resolveartifacts.directory,use_obsidian_cli, andtemplate. Determine the current local date and time (YYYYMMDD_HHMM) for the filename. - If
templateis set, read the template file: withuse_obsidian_cli = trueor a vault named explicitly, runpython3 <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. - 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 ofuse_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 runscripts/obsidian_stock.py createas described above — it handles the naming rule and the directory itself.
- A vault was named explicitly: write the body to a temp file and run
- Tell the user the saved path and briefly summarize what was captured.
- 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 viascripts/obsidian_stock.py overwritewhen 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
obsidianCLI 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--plainwas in the invoking ARGUMENTS — never both - the
会話内容section is a verbatim transcript of the actual exchange, not a summary or paraphrase — unless--simplifywas 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--simplifywas 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
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
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.

