session-manager · diff
git:20260913.09e57f7 to git:20260915.546fea0
51 added, 118 removed. Audit A to A.
---
name: session-manager
- description: Manage current Claude Code session metadata — set project, tags, and summary on session.md via Obsidian CLI. Use this skill whenever the user wants to tag, categorize, name, label, summarize, or organize the current session. Triggers on phrases like "tag this session", "this was about X", "mark this as", "session summary", "call this session", "categorize this as", "set project to", or any mention of session metadata or session organization. Even if the user just casually mentions what the session was about ("we were working on the auth refactor"), use this skill to offer to set tags.
+ description: Set the current session's name, project, tags, or summary on its session note. Use when the user names, tags, or summarizes this session, sets its project, or mentions in passing what this session has been about.
---
# Session Manager
- Manage metadata for the current active session's `session.md` file via Obsidian CLI.
+ You **own** four properties on the current session's note: `session_name`, `project`, `tags` and
+ `summary`. The hooks own every other property, so those four are the only ones you write.
- ## Deriving the Session Path
+ | Property | Type | Holds |
+ |----------|------|-------|
+ | `session_name` | text | The session's name, kept in step with `/rename` |
+ | `project` | text | Project name, seeded from the working directory and yours to override |
+ | `tags` | list | Categorization, drawn from the vault's existing tags |
+ | `summary` | text | One line on what the session accomplished |
- The session docs path is injected into your system prompt by the SessionStart hook. It looks like:
+ ## Preflight
+ Run all five steps on every invocation, before the user's request and whatever they asked for.
+
+ **1. Locate the note.** The SessionStart hook injects a docs path into your system prompt:
+
```
Session docs path: {KB_PATH}/_sessions/2026-03-04/abc123-def456/docs/
```
- To get the `session.md` vault-relative path for Obsidian CLI:
-
- 1. Take the injected docs path
- 2. Find `_sessions/` in it — everything from `_sessions/` onward is vault-relative
- 3. Remove the trailing `docs/` and append `session.md`
-
- **Example:**
- - Injected: `.../knowledge-bank/_sessions/2026-03-04/abc123-def456/docs/`
- - Vault-relative session.md: `_sessions/2026-03-04/abc123-def456/session.md`
-
- If the session docs path is not in your system prompt, ask the user for the session folder path.
-
- ## Properties You Can Update
-
- | Property | Type | Purpose |
- |----------|------|---------|
- | `session_name` | text | Session name (auto-synced from `/rename` customTitle on invocation) |
- | `project` | text | Project name (auto-set from cwd at session start, customizable) |
- | `tags` | list | Freeform categorization (e.g., brainstorming, debugging, architecture) |
- | `summary` | text | One-line description of what the session accomplished |
-
- Do NOT modify other frontmatter properties (session_id, date, cwd, etc.) — those are managed by hooks.
-
- ## Commands
-
- **Set a property:**
- ```bash
- obsidian vault="knowledge-bank" property:set name="<property>" value="<value>" [type="list"] path="<vault-relative-path>"
- ```
+ Everything from `_sessions/` onward is vault-relative. Drop the trailing `docs/` and append
+ `session.md`, giving `_sessions/2026-03-04/abc123-def456/session.md`. Read it:
- **Read current metadata:**
```bash
obsidian vault="knowledge-bank" read path="<vault-relative-path>"
```
- ## Tag Suggestion Workflow
-
- When the user wants to set tags, **do NOT set them directly**. Instead, suggest existing tags to promote consistency.
+ If no docs path was injected, ask the user for the session folder.
- ### Step 1: Load existing tags
+ **2. Sync the name.** `/rename` writes a `customTitle` to the transcript, which the note does not see:
- Read from ccfind's cache (field 5, comma-separated):
```bash
- CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/ccfind/sessions.tsv"
- cut -f5 "$CACHE" 2>/dev/null | tr ',' '\n' | sed 's/^ *//;s/ *$//' | grep -v '^-$' | grep -v '^$' | sort -u
+ source skills/common/obsidian_helpers.sh
+ read_custom_title "<cwd from the note>" "<session_id from the note>"
```
- If the cache doesn't exist, fall back to listing tags from the current session's tags property.
-
- ### Step 2: Match user-provided tags against existing ones
-
- For each tag the user provides, check for:
- - **Exact match** — existing tag matches exactly → use it
- - **Similar match** — differs only by hyphenation (`rule-forge` vs `ruleforge`), casing (`A2X` vs `a2x`), or minor spelling → suggest the existing one
- - **No match** — genuinely new tag → mark as new
-
- ### Step 3: Present suggestion table
+ When that title differs from `session_name`, adopt it:
- ```
- | Your Tag | Suggestion | Reason |
- |----------------|---------------------|---------------------|
- | rule-forge | → ruleforge (6×) | existing, no hyphen |
- | debugging | ✓ debugging (6×) | exact match |
- | new-feature | new | no similar existing |
+ ```bash
+ obsidian vault="knowledge-bank" property:set name="session_name" value="<title>" path="<vault-relative-path>"
```
- The `(N×)` shows how many sessions already use that tag — higher = more reason to reuse.
-
- ### Step 4: Confirm before setting
+ **3. Name the terminal.** Give the enclosing container the session's name, as a real Bash call. The
+ helper detects tmux or Herdr from `$TMUX_PANE` and `$HERDR_PANE_ID` itself, and under Herdr it also
+ names the agent so other agents can reach this session by name:
- Use the **AskUserQuestion** tool to confirm. Only set tags after the user approves:
- ```
- AskUserQuestion({ question: "Suggested tags: [table]. Confirm or adjust?" })
+ ```bash
+ source skills/common/obsidian_helpers.sh
+ rename_terminal_window "<session_name>"
```
- ## Examples
+ The helper is best-effort and reports nothing, so confirm the result yourself rather than assuming it:
- User: "set project to sundayhao-plugins"
```bash
- obsidian vault="knowledge-bank" property:set name="project" value="sundayhao-plugins" path="_sessions/2026-03-04/abc123/session.md"
+ [ -n "$HERDR_PANE_ID" ] && herdr pane list | grep -o "\"label\":\"[^\"]*\"" | grep -c "<session_name>"
+ [ -n "$TMUX_PANE" ] && tmux display-message -p '#W'
```
- User: "add tags brainstorming and architecture"
+ **Done when:** the container's label reads back as the session name, or `session_name` is empty and
+ there was nothing to apply.
- **Do NOT run the command directly.** Instead:
- 1. Load existing tags (Step 1)
- 2. Both `brainstorming` and `architecture` exist — show confirmation table
- 3. After user confirms, then set:
- ```bash
- obsidian vault="knowledge-bank" property:set name="tags" value="brainstorming, architecture" type="list" path="_sessions/2026-03-04/abc123/session.md"
- ```
+ **4. Report the four properties.**
- User: "summarize: designed centralized session management"
- ```bash
- obsidian vault="knowledge-bank" property:set name="summary" value="Designed centralized session management for second-brain plugin" path="_sessions/2026-03-04/abc123/session.md"
```
-
- User: "what's this session tagged as?"
- ```bash
- obsidian vault="knowledge-bank" read path="_sessions/2026-03-04/abc123/session.md"
+ **Current Session**
+ - session_name: <value or empty>
+ - project: <value or empty>
+ - tags: <value or empty>
+ - summary: <value or empty>
```
- Then extract and report the `tags` and `summary` from the frontmatter.
- ## On Invocation
+ **5. Dispatch.** Carry out the user's request. When the request names no property, ask with the
+ **AskUserQuestion** tool which of the four to update.
- Every time this skill is invoked, **always** perform steps 1-4 before handling the user's request. These steps run on **every invocation regardless** of what the user asked (tags, summary, or anything else):
+ ## Writing a property
- 1. Read the session note using the "Read current metadata" command
- 2. Check if the session has been renamed via `/rename` by reading the customTitle from the transcript:
- ```bash
- source skills/common/obsidian_helpers.sh
- read_custom_title "<cwd>" "<session_id>"
- ```
- Where `<cwd>` is from session.md's `cwd` property and `<session_id>` is from `session_id` property.
- 3. If customTitle exists but `session_name` in session.md is empty or different, **automatically set it**:
- ```bash
- obsidian vault="knowledge-bank" property:set name="session_name" value="<customTitle>" path="<vault-relative-path>"
- ```
- 4. **Always rename the terminal container** (tmux window or Herdr pane) to the current session_name (whether from customTitle or already in session.md). Under Herdr this also names the agent in the pane after the session_name (sanitized to Herdr's `[a-z][a-z0-9_-]{0,31}` rule), so other agents can target it via `herdr agent <cmd> <name>`. This MUST run on every invocation:
- ```bash
- source skills/common/obsidian_helpers.sh
- rename_terminal_window "<session_name>"
- ```
- Run this as an actual Bash tool call. The helper detects the environment itself: `$TMUX_PANE` (tmux) and/or `$HERDR_PANE_ID` (Herdr) are available in Claude's shell environment. Skip only if session_name is empty.
- 5. Display current values in this format:
- ```
- **Current Session**
- - session_name: <value or empty>
- - project: <value or empty>
- - tags: <value or empty>
- - summary: <value or empty>
- ```
- 6. Then proceed with the user's request. If the request is ambiguous or the skill was invoked without a specific request, use the **AskUserQuestion** tool:
- ```
- AskUserQuestion({ question: "What would you like to update?\n- tags\n- summary\n- project" })
- ```
+ ```bash
+ obsidian vault="knowledge-bank" property:set name="<property>" value="<value>" [type="list"] path="<vault-relative-path>"
+ ```
- ## Constraints
+ Tags take an extra step: they are canonicalized against the vault's existing tags and confirmed
+ before anything is written. Read [tag-canonicalization.md](tag-canonicalization.md) when the request
+ involves tags.
- - ONLY operates on the **current active session** — do NOT modify other sessions
- - ONLY updates `session_name`, `project`, `tags`, and `summary`
- - **Use AskUserQuestion tool** for all confirmations and prompts (not plain text questions). This ensures the user gets a proper input prompt.
- - Always confirm the update to the user after running the command
+ Confirm every write back to the user, and use the **AskUserQuestion** tool for confirmations so the
+ user gets a real prompt. This skill acts on the current session alone.