AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Session Notes

skill-jojoprison-mnemo-session-notes · by jojoprison

Use when significant work wraps up — a feature shipped, a bug fixed, a research thread finished, before the user steps away — and also mid-task as a checkpoint before a long run risks context compaction (it updates the same session note + handoff, never spawns a duplicate). Also on 'записать сессию', 'сохрани сессию', 'отложи сессию в память', 'сессию в обсидиан', 'закругляйся с сессией', 'sessio…

No reviews yet
0 installs
38 views
0.0% view→install

Install

$ agentstack add skill-jojoprison-mnemo-session-notes

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-jojoprison-mnemo-session-notes)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Session Notes? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mnemo:session — Session Notes to Obsidian

Create a human-readable session summary note in Obsidian after significant work.

Prerequisites & config

Obsidian must be open. Config at ~/.mnemo/config.json — reads vault, taxonomy.session, links_section, handoff_note. Schema in ${CLAUDE_PLUGIN_ROOT}/references/config-schema.md.

Tool-routing (MCP for writes, CLI for reads/search) in ${CLAUDE_PLUGIN_ROOT}/references/tool-routing.md. Frontmatter template in ${CLAUDE_PLUGIN_ROOT}/assets/session-template.md.

When to Trigger

  • After completing a feature / PR / fix
  • After significant research session
  • Manually via /mn:session
  • Do NOT trigger for trivial tasks (typo fix, one-liner). Research / exploration / personal-curiosity sessions are NOT trivial — they get a note even with zero code. When unsure, create: a session note is cheap, a lost session is not.

Workflow

Step 1: Summarize Current Session

Mid-task checkpoint vs end-of-session note. If this is a mid-task checkpoint (a long run risks compaction and you're saving progress, not wrapping up) and a note for this same session already exists — match by the session_id you'd write in frontmatter (or the filename derived earlier this session) — update that note in place (mcp__obsidian__str_replace to refresh the summary and append new progress) plus refresh the handoff (Step 5). Do not create a second note for the same session — that fragments the record. Only a genuinely new session or a distinct topic gets a new note.

Analyze the conversation: what was done, key decisions, commits/PRs created, findings.

Ground the summary in facts — don't rely on conversation memory alone (a note that claims "shipped X" when git shows no such commit is worse than no note). Before writing "what was done", cross-check against reality: git log --oneline -15 + git status --short for real commits/changes, and — when the script is reachable — the session's actual tool/skill activity:

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/session-scan.py" 2>/dev/null | head -30 \
  || python3 "$(ls -d "$HOME/.claude/plugins/cache/"*"/mnemo/"*"/plugins/mnemo/scripts/session-scan.py" 2>/dev/null | head -1)" 2>/dev/null | head -30

Reconcile claimed outcomes with these before persisting — the same grounding /mn:review does, applied to the note /mn:session writes directly.

Derive a planned filename: {session_prefix}{YYYY-MM-DD} {short descriptive topic}. Topic should be specific enough to disambiguate from other sessions the same day (include PR number, Linear ticket, branch name, or primary keyword).

Naming: the topic must NOT contain #, ., or / — they break wikilinks (#→heading anchor) or the CLI (.→truncation). Write PR 387, not PR #387. See ${CLAUDE_PLUGIN_ROOT}/references/tool-routing.md (naming rules).

Step 2: Duplicate Check (two-level, parallel)

Run Level 1 and Level 2 in parallel — single assistant message with two Bash tool uses. ~185ms total instead of ~370ms sequential.

Level 1 — exact filename:

obsidian read file="{planned-filename}" vault="{vault}" 2>/dev/null | head -5

If the read returns content → a note with this EXACT filename already exists. Do NOT silently skip and do NOT auto-overwrite. Offer append / overwrite / rename, leading with append/continuation. To append, use mcp__obsidian__insert (at the file's last line) or mcp__obsidian__str_replace to add a ## part 2 / ## continuation section — NOT mcp__obsidian__create (it only creates new files and will fail or clobber an existing one). Overwrite only if the user is clearly regenerating the same session.

Level 2 — related same-day sessions (informational only):

obsidian search query="{session_prefix}{YYYY-MM-DD}" vault="{vault}"

These are NOT duplicates — same day, different topics. Doing many sessions in one day is normal: each distinct topic gets its OWN note. A Level-2 same-day match is context, NOT a reason to skip creation or to assume the note already exists — that mistake silently loses sessions. Show the list to the user so they can:

  • Decide if this session should be merged into an existing one
  • Remember to cross-link related sessions via ## Связи / ## Links

Do not block creation on Level 2 matches — they're context, not conflicts.

Step 3: Create Session Note (MCP — primary; Codex fallback below)

In Claude, always use mcp__obsidian__create for creation. Never CLI with inline content= (shell-injection). In Codex, where the Obsidian MCP isn't available, take the Codex fallback at the end of this step instead — the inline-content= ban still holds there.

First, read the template (provides the exact structure to follow):

cat "${CLAUDE_PLUGIN_ROOT}/assets/session-template.md" 2>/dev/null \
  || cat "$(ls -d "$HOME/.claude/plugins/cache/"*"/mnemo/"*"/plugins/mnemo/assets/session-template.md" 2>/dev/null | head -1)" 2>/dev/null \
  || cat "$(ls -d "$HOME/.codex/plugins/cache/"*"/mnemo/"*"/assets/session-template.md" 2>/dev/null | head -1)"

Then create the note, filling the template placeholders ({Session Title}, {YYYY-MM-DD}, {project}, etc.) with the current session's context:

mcp__obsidian__create(
  path: "{planned-filename}.md",
  file_text: ""
)

Where {session_prefix} comes from config.taxonomy.session.prefix, {links_section} from config.links_section, and the session id from {CLAUDE_SESSION_ID} — or {CODEX_SESSION_ID} under Codex — in the environment (empty string if neither is available).

Why MCP here: frontmatter and body may contain any markdown — code blocks with backticks, $(...) samples, shell snippets. MCP passes file_text as a JSON parameter; no shell involved.

Codex fallback (no Obsidian MCP, no safe CLI create): the human-readable Obsidian note is a Claude-path deliverable, and there is no shell-safe way to create it with a markdown body from Codex. So instead of failing silently or running an unsafe inline content=, write the filled summary to the local fallback memory — ~/.codex/memories/session-{YYYY-MM-DD}-{HHMM}.md (include the time so two sessions the same day don't overwrite each other) — and tell the user the full vault note needs a Claude/Obsidian session. This degrades gracefully and preserves the content.

Step 4: Verify MOC Link

Read MOC (CLI — safe, read-only):

obsidian read file="{MOC name}" vault="{vault}"

Check if the new session note is listed.

If missing — append link (MCP preferred):

mcp__obsidian__str_replace(
  path: "{MOC name}.md",
  old_str: "{some stable anchor line near the session list}",
  new_str: "{same anchor}\n- [[{session note name}]]"
)

Alternatively, if the MOC has a predictable append point, use mcp__obsidian__insert with a line number.

CLI fallback (only if link text has no backticks/$()): obsidian append file="{MOC}" content="- [[{name}]]" — a plain wikilink is safe, but prefer MCP for consistency.

Step 5: Update Session Handoff

Read handoff (CLI — safe):

obsidian read file="{handoff_note}" vault="{vault}"

Update with MCP str_replace — targeted, not blind append:

  • Remove completed pending items from previous sessions
  • Add new pending items from current session (if any)
  • Update context carry-over section
mcp__obsidian__str_replace(
  path: "{handoff_note}.md",
  old_str: "{old section content}",
  new_str: "{updated section content}"
)

If handoff note doesn't exist, create it via mcp__obsidian__create (same structure as initial-setup Step 6).

Size-guard — keep the handoff thin (run every session):

The handoff is a LIVE index, not an archive. After updating it, run the archival helper so closed history doesn't accumulate into a multi-MB token bomb (it no-ops when the note is at/under handoff.maxKB):

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/handoff-archive.py" \
  --vault-path "$(bash "${CLAUDE_PLUGIN_ROOT}/scripts/get-vault-path.sh" "{vault}")" \
  --handoff "{handoff_note}" --max-kb {handoff.maxKB:-40} --keep-days {handoff.keepDays:-14} --execute

Keeps HOT: entries with an open - [ ] + the last keepDays. Moves CLOSED older entries verbatim to {handoff_note} Archive (cold, not read at session start; a .bak- is written for undo). Their durable detail already lives in the linked Session — … notes. Mirrors the MEMORY.md size-guard (thin hot index + cold archive + header pointer). If the vault path can't be resolved (Obsidian absent), skip — degrade gracefully.

Step 6: Orphan Check

obsidian orphans vault="{vault}"

If the newly created note appears in orphans, it means no ## Связи links or the MOC didn't get updated.

⚠️ obsidian orphans caches & lags writes 1-5s — a note created moments ago via MCP may show as orphan falsely. If it appears right after creation, wait 2-3s and re-run, or verify authoritatively via obsidian eval (metadataCache.resolvedLinks/unresolvedLinks). See ${CLAUDE_PLUGIN_ROOT}/references/gotchas.md.

Step 7: Confirm

Output summary:

  • Note name
  • MOC updated (yes/no)
  • Handoff updated (yes/no)
  • Orphan status (clean / flagged)

Rules

  • MCP for any write with markdown body — non-negotiable, shell-safety
  • CLI for read/search/index — faster, indexed, unique functions
  • No inline obsidian create content="..." with markdown — banned: zsh expands backticks / $(...) in the body (real incident: nearly ran make deploy-back)
  • Two-level duplicate check — exact-read + same-day-search
  • Include session_id in frontmatter — disambiguates same-day sessions
  • No session notes for trivial work — but "trivial" = mechanical one-liners only (typo, single rename). A research / exploration / curiosity session counts as significant even with zero code; default to creating.
  • Branch field optional — research sessions don't have branches
  • Handoff = thin live index, not an archive — targeted str_replace, not blind append. Named ceiling: when it exceeds handoff.maxKB (default 40KB), scripts/handoff-archive.py (Step 5) rotates CLOSED blocks older than handoff.keepDays into {handoff_note} Archive (cold); open - [ ] + recent stay hot. Prevents multi-MB token-bomb accumulation.
  • Links section is mandatory — at least one MOC link, else the note orphans (invisible to graph navigation)
  • Ghost notes generously — wrap projects, technologies, people in [[wikilinks]]

Gotchas

Common failures (IPC hung, shell injection) in ${CLAUDE_PLUGIN_ROOT}/references/gotchas.md. Skill-specific rules:

  • MCP create signature: path (not name), file_text (not content). Path is relative to vault root, include .md extension.
  • Always check duplicate before creating — prevents clobbering same-day work. Two-level check in Step 2.
  • str_replace requires exact match — copy the anchor text verbatim from read output, including whitespace.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.