- name
- obs-memory
- description
- Persistent Obsidian-based memory for coding agents. Use at session start to orient from a knowledge vault, during work to look up architecture/component/pattern notes, and when discoveries are made to write them back. Activate when the user mentions obsidian memory, obsidian vault, obsidian notes, or /obs commands. Provides commands: init, analyze, recap, project, note, todo, lookup, relate.
- metadata
- {"author":"adamtylerlynch","version":"2.2"}
- license
- MIT
# Obsidian Agent Memory
You have access to a persistent Obsidian knowledge vault — a graph-structured memory that persists across sessions. Use it to orient yourself, look up architecture and component knowledge, and write back discoveries.
## Vault Discovery
Resolve the vault path using this chain (first match wins):
1. **Environment variable**: `$OBSIDIAN_VAULT_PATH`
2. **Agent config reference**: Parse the vault path from the agent's project or global config (look for "Obsidian Knowledge Vault" section with a path like `~/Documents/SomeName/`)
3. **Default**: `~/Documents/AgentMemory`
Store the resolved path as `$VAULT` for all subsequent operations. Derive `$VAULT_NAME` as `basename "$VAULT"` for CLI calls.
Verify the vault exists by checking for `$VAULT/Home.md`. If the vault doesn't exist, inform the user and suggest running the `init` command to bootstrap a new vault from the bundled template.
## Session Start — Orientation
At the start of every session, orient yourself with **at most 2 operations**:
### Step 1: Read TODOs
**CLI-first**:
```bash
obsidian vault=$VAULT_NAME tasks path="todos" todo verbose
```
**Fallback**: Read the file at `$VAULT/todos/Active TODOs.md`.
Know what's pending, in-progress, and recently completed.
### Step 2: Detect current project and read its overview
Auto-detect the project from the current working directory:
```bash
basename $(git rev-parse --show-toplevel 2>/dev/null) 2>/dev/null || basename $(pwd)
```
Then check if a matching project exists by listing files in `$VAULT/projects/*/`. Match the git repo name (or directory name) against project folder names. If a match is found, read the project overview at `$VAULT/projects/{matched-name}/{matched-name}.md`.
This project overview contains wikilinks to all components, patterns, architecture decisions, and domains. **Do not read those linked notes yet** — follow them on demand when the current task requires that context.
### What NOT to read at session start
- `Home.md` (only if you're lost and can't find the project)
- `sessions/` (only if the user references prior work)
- Domain indexes (only if you need cross-project knowledge)
- Component notes (only when working on that component)
## Automatic Behaviors
These behaviors apply to any agent using this skill. They do not require explicit commands.
### On session start
Auto-orient (TODOs + project overview) without being asked, following the Session Start procedure above. If the vault doesn't exist at the resolved path, inform the user and suggest running `init`.
### On session end signals
When the user says "done", "wrapping up", "that's it", "let's stop", or similar end-of-session language — offer to write a session summary. Don't auto-run; ask first: "Want me to write a session summary to the vault before we wrap up?"
### On component discovery
When you deeply analyze a component that has no vault note — and the project has an active vault — offer to create a component note and infer relationships from imports and dependencies. Example: "I noticed there's no vault note for the AuthMiddleware component. Want me to create one and map its dependencies?"
### On first run
When the vault doesn't exist at any resolved path, guide the user through `init`, then auto-scaffold the current project if inside a git repo.
## During Work — Graph Navigation
**Principle: Use CLI queries first, file reads second.** The Obsidian CLI provides structured access to properties, links, backlinks, tags, and search — prefer these over reading entire files.
### CLI-first lookups (preferred)
Use these CLI commands for targeted queries without consuming file-read tokens:
```bash
# Query a component's dependencies
obsidian vault=$VAULT_NAME property:read file="Component Name" name="depends-on"
# Find what depends on a component
obsidian vault=$VAULT_NAME property:read file="Component Name" name="depended-on-by"
obsidian vault=$VAULT_NAME backlinks file="Component Name"
# Find all outgoing links from a note
obsidian vault=$VAULT_NAME links file="Component Name"
# Find all notes of a type
obsidian vault=$VAULT_NAME tag verbose name="component"
# Search vault content
obsidian vault=$VAULT_NAME search format=json query="search term" matches limit=10
# Get note structure without full read
obsidian vault=$VAULT_NAME outline file="Component Name"
# Read a specific property
obsidian vault=$VAULT_NAME property:read file="Component Name" name="key-files"
```
Where `$VAULT_NAME` is the vault folder name (basename of `$VAULT`).
### File-read fallback (when CLI unavailable)
Fall back to file reads when the Obsidian CLI is not available:
- Need to understand a component? The project overview links to it. Read that one note.
- Need an architecture decision? The component note or project overview links to it. Follow the link.
- Need cross-project knowledge? Component/pattern notes link to domain notes. Follow the link.
- Need session history? Only read if you're stuck or the user references prior work.
### Frontmatter-first scanning
When you need to scan multiple notes to find the right one, read just the first ~10 lines of each file. The `tags`, `project`, `type`, and `status` fields in the frontmatter tell you if the note is relevant before reading the full body.
### Directory listing before reading
List directory contents before reading files — know what exists without consuming tokens:
- `$VAULT/projects/{name}/**/*.md` — all notes for a project
- `$VAULT/domains/{tech}/*.md` — domain knowledge files
## Writing to the Vault
Write concisely. Notes are for your future context, not human documentation. Prefer:
- Bullet points over prose
- Wikilinks over repeated explanations (link to it, don't re-state it)
- Frontmatter tags for discoverability over verbose descriptions
### When to write
- **New component discovered**: Create a component note when you deeply understand a part of the codebase
- **Architecture decision made**: Record ADRs when significant design choices are made
- **Pattern identified**: Document recurring patterns that future sessions should follow
- **Domain knowledge learned**: Write to domain notes when you discover cross-project knowledge
### Scoping rules
| Knowledge type | Location | Example |
|---|---|---|
| One project only | `projects/{name}/` | How this API handles auth |
| Shared across projects | `domains/{tech}/` | How Go interfaces work |
| Universal, tech-agnostic | `patterns/` | SOLID principles |
| Session summaries | `sessions/` | What was done and discovered |
| TODOs | `todos/Active TODOs.md` | Grouped by project |
### Frontmatter conventions
Always include in new notes:
```yaml
---
tags: [category, project/short-name]
type: <component|adr|session|project>
project: "[[projects/{name}/{name}]]"
created: YYYY-MM-DD
---
```
### Wikilink conventions
- Link to related notes: `[[projects/{name}/components/Component Name|Component Name]]`
- Link to domains: `[[domains/{tech}/{Tech Name}|Tech Name]]`
- Link back to project: `[[projects/{name}/{name}|project-name]]`
### Note templates
**Component Note:**
```yaml
---
tags: [components, project/{short-name}]
type: component
project: "[[projects/{name}/{name}]]"
created: {date}
status: active
layer: ""
depends-on: []
depended-on-by: []
key-files: []
---
```
Sections: Purpose, Gotchas
**Architecture Decision:**
```yaml
---
tags: [architecture, decision, project/{short-name}]
type: adr
project: "[[projects/{name}/{name}]]"
status: proposed | accepted | superseded
created: {date}
---
```
Sections: Context, Decision, Alternatives Considered, Consequences
**Session Note:**
```yaml
---
tags: [sessions]
type: session
projects:
- "[[projects/{name}/{name}]]"
created: {date}
branch: {branch-name}
---
```
Sections: Context, Work Done, Discoveries, Decisions, Next Steps
## Commands
### `init` — Initialize the Vault
Bootstrap a new Obsidian Agent Memory vault from the bundled template.
**Usage**: `init [path]`
#### Steps:
1. **Determine vault path**: Use the first argument if provided, otherwise use the vault resolution chain (default: `~/Documents/AgentMemory`).
2. **Check if vault already exists**: Look for `$VAULT/Home.md`. If it exists, tell the user the vault already exists at that path and offer to open it.
3. **Locate the bundled template**: The template is at `vault-template/` relative to the skill package root. Search for the skill package installation directory — it may be in the agent's plugin/skill cache or a local checkout. Look for the `vault-template/Home.md` file to confirm the correct path.
4. **Create the vault**:
```bash
mkdir -p "$VAULT"
cp -r "$TEMPLATE_DIR/vault-template/"* "$VAULT/"
```
5. **Create Obsidian config directory**:
```bash
mkdir -p "$VAULT/.obsidian"
```
Write the following to `$VAULT/.obsidian/app.json`:
```json
{
"alwaysUpdateLinks": true,
"newFileLocation": "folder",
"newFileFolderPath": "inbox",
"attachmentFolderPath": "attachments"
}
```
6. **Create empty directories**:
```bash
mkdir -p "$VAULT/inbox"
mkdir -p "$VAULT/attachments"
```
Create `.gitkeep` files in each empty directory.
7. **Report** the created vault and provide next steps:
- Open in Obsidian: Vault Switcher → Open folder as vault → `$VAULT`
- Set the vault path via `OBSIDIAN_VAULT_PATH` environment variable or agent config
- Start working — the agent will build the knowledge graph as it goes
8. **Generate agent config snippet**: Output a vault path snippet appropriate for the user's agent. For Claude Code, output a `CLAUDE.md` snippet:
```markdown
## Obsidian Knowledge Vault
Persistent knowledge vault at `$VAULT`.
```
For other agents, output a generic instruction: "Add `OBSIDIAN_VAULT_PATH=$VAULT` to your environment or agent config."
9. **Auto-scaffold current project**: If inside a git repo, automatically run the `project` command to scaffold the current project in the vault.
10. **Concise output**: Keep the final output to 5-8 lines max: vault path created, project scaffolded (if applicable), how to open in Obsidian, how to set the vault path.
### `analyze` — Analyze Project & Hydrate Vault
Analyze the current codebase and populate the vault with interconnected, content-rich notes.
**Usage**: `analyze` (no arguments — uses current repo)
#### Phase 1: Discovery — Scan for Knowledge Sources
Scan the repo for files that contain pre-existing knowledge:
| Category | Files to scan |
|---|---|
| Agent configs | `CLAUDE.md`, `.claude/CLAUDE.md`, `.cursorrules`, `.windsurfrules`, `.clinerules`, `AGENTS.md`, `Agents.md` |
| Documentation | `README.md`, `CONTRIBUTING.md`, `ARCHITECTURE.md`, `docs/architecture.md`, `docs/ARCHITECTURE.md` |
| Existing ADRs | `docs/adr/ADR-*.md`, `architecture/ADR-*.md`, `adr/*.md`, `docs/decisions/*.md` |
| Project metadata | `package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `setup.py`, `Gemfile`, `pom.xml`, `build.gradle`, `*.csproj` |
| Build/CI | `Makefile`, `Dockerfile`, `docker-compose.yml`, `.github/workflows/*.yml`, `.gitlab-ci.yml` |
| Config | `tsconfig.json`, `.eslintrc.*`, `jest.config.*`, `.goreleaser.yml` |
Read each discovered file. For large files (README, agent configs), read fully. For metadata files, extract key fields (name, version, dependencies).
Also gather:
- Repo URL from `git remote get-url origin`
- Repo root path from `git rev-parse --show-toplevel`
- Active branch from `git branch --show-current`
- Directory tree (top 2 levels of source directories, excluding hidden/vendor/node_modules)
- File extension frequency (for language detection)
#### Phase 2: Analysis — Extract & Synthesize
Using the discovered content, synthesize:
1. **Project metadata**: name, language(s), framework(s), repo URL, local path
2. **Architecture summary**: Entry points, layer organization (e.g., `internal/` → Go service layers, `src/components/` → React app), build system
3. **Component inventory**: Major functional modules — each top-level source directory or logical grouping that represents a distinct unit. For each: purpose (from README/agent config context), key files, and relationships
4. **Pattern inventory**: Coding conventions, error handling strategies, testing approaches — extracted from agent config files (CLAUDE.md sections like "Coding Guidelines", "Testing", etc.)
5. **Domain mapping**: Detected technologies → vault domain notes (e.g., Go, TypeScript, Terraform, React)
6. **Existing decisions**: ADR files found in the repo → import as vault ADR notes
7. **Dependency summary**: Key dependencies from package manifests (listed in project overview, not separate notes)
#### Phase 3: Hydration — Write Vault Notes
**Idempotency rules:**
- If project directory doesn't exist → create everything (scaffold + populate)
- If project directory exists but overview is a skeleton → **replace** overview with populated version
- If individual component/pattern/ADR notes already exist → **skip** and report (don't overwrite manual work)
- Domain notes: create if missing, **append** project link if existing
**Notes to write:**
1. **Project overview** (`$VAULT/projects/{name}/{name}.md`) — Fully populated:
```yaml
---
aliases: []
tags: [project/{short-name}]
type: project
repo: {git remote url}
path: {repo root path}
language: {detected language(s)}
framework: {detected framework(s)}
created: {YYYY-MM-DD}
status: active
---
```
Sections:
- **Architecture**: Real description from analysis
- **Components**: Table with wikilinks to component notes
- **Project Patterns**: Table with wikilinks to pattern notes
- **Architecture Decisions**: List with wikilinks to ADR notes
- **Key Dependencies**: From package manifests
- **Domains**: Wikilinks to domain notes
2. **Component notes** (`$VAULT/projects/{name}/components/{Component}.md`) — One per major module:
```yaml
---
tags: [components, project/{short-name}]
type: component
project: "[[projects/{name}/{name}]]"
created: {YYYY-MM-DD}
status: active
layer: {detected layer}
depends-on: []
depended-on-by: []
key-files: [{key files list}]
---
```
عرض على GitHub