Thanks for your interest in contributing! This skill exists because the people who use it keep making it better. Whether you're filing a bug, requesting a feature, or shipping a new command, you're welcome here.
This guide explains how to contribute so your work lands fast.
- Be respectful. This project follows a Code of Conduct. Disagreement is welcome; rudeness is not.
- Search first. Check open issues and discussions. Someone may already be working on what you're proposing.
- For ideas / questions / "what if...", prefer Discussions. Issues are for concrete bugs or feature proposals.
- 📜 AI-first vault rule — required reading before adding any command that writes to the vault
- 📖 SKILL.md — the operating manual for Claude
- 🏗 architecture.md — how the layers fit together
- 🐛 Bug report form
- ✨ Feature request form
# Clone the repo
git clone https://github.com/eugeniughelbur/obsidian-second-brain ~/Projects/obsidian-second-brain
cd ~/Projects/obsidian-second-brain
# Install Python deps via uv (auto-creates .venv)
uv sync
# Set up API keys for the research toolkit (optional — only needed if you're working on /x-read, /x-pulse, /research, /research-deep, or /youtube)
mkdir -p ~/.config/obsidian-second-brain
cp .env.example ~/.config/obsidian-second-brain/.env
chmod 600 ~/.config/obsidian-second-brain/.env
# then paste your xAI / Perplexity / YouTube keys into the file
# Link the skill into Claude Code (if you're testing slash commands)
ln -s "$(pwd)" ~/.claude/skills/obsidian-second-brain
ln -s commands/* ~/.claude/commands/Now restart Claude Code and your slash commands will use the local checkout.
- File a bug report first if one doesn't exist (use the form so you don't miss required info)
- Reproduce locally
- Fix on a branch named
fix/short-description - Open a PR linking the issue:
Closes #123
This is the most common contribution. The skill currently has 31 commands across 4 layers; adding a 32nd is a clear path.
Required steps:
- Open a feature request issue first. Get a thumbs-up before building. Saves you wasted work if the command isn't a fit.
- Add
commands/<command-name>.mdwith frontmatter and instructions - If the command runs Python (research-style), add
scripts/research/<script>.py - Apply the AI-first rule to any vault writes. This is non-negotiable. Every saved note must:
- Have a
## For future Claudepreamble - Have rich frontmatter (
type,date,tags,ai-first: true, plus type-specific fields) - Use
[[wikilinks]]for every person, project, idea, decision referenced - Preserve external claims with recency markers (
(as of 2026-04, source.com)) - Include source URLs verbatim
- Mark confidence where applicable (
stated | high | medium | speculation)
- Have a
- Update
SKILL.md— add a section under the appropriate Layer with the command name and full operating instructions - Update
README.md— add the command to the relevant table in the "Commands" section - Update
references/ai-first-rules.md— if your command produces a NEW note type, add its frontmatter schema there - Add an entry to
CHANGELOG.mdunder "Unreleased"
Adding a new research source (Reddit, podcasts, papers, etc.) follows the same path as a new command, plus:
- Document API setup in
.env.exampleand the README's "Research toolkit" install section - Add the API key to
scripts/research/lib/config.pywithget_optional()(degrades gracefully if missing) - Use the
lib/grok.pyandlib/perplexity.pypatterns for retry + error handling
Documentation PRs are always welcome. Specifically helpful:
- Examples of vault setups for different roles (founder, researcher, student)
- Screenshots of real vault notes after running specific commands
- Translation of docs into other languages
- Fixing typos and unclear wording
No issue required for typo fixes — just open a PR.
Every command in commands/<name>.md declares trigger phrases per language in its frontmatter:
---
description: Save everything worth keeping from this conversation to the vault
category: vault
triggers_en: ["save this", "save the conversation", "save to vault", "obsidian save"]
---To add a new language, add a triggers_<two-letter-code>: line right after the existing triggers_en: line, with a list of equivalent phrases in that language. Important: use natural, conversational phrases a native speaker would actually say — not literal word-for-word translations of the English.
Supported language codes (add more by editing _lang_label() in adapters/lib.sh):
| Code | Label |
|---|---|
en |
English |
es |
Español |
it |
Italiano |
fr |
Français |
de |
Deutsch |
pt |
Português |
ru |
Русский |
ja |
日本語 |
Example: adding Spanish to obsidian-save:
triggers_en: ["save this", "save the conversation", "save to vault"]
triggers_es: ["guarda esto", "guarda la conversación", "guarda al vault"]When you rebuild (bash scripts/build.sh), the new language automatically appears as its own section under ## Trigger phrases in the dispatcher files (AGENTS.md, GEMINI.md). No adapter code changes needed.
Translation PRs welcome for any of the 31 commands. Send one language at a time, full coverage. Open commands/*.md, add your triggers_<code>: line under the existing triggers_en:, and open a PR titled Add <Language> trigger phrases.
The skill currently assumes macOS (install.sh, ~/.config paths, the open command for auto-opening notes in Obsidian). Linux/Windows support PRs are welcome. Touch:
install.sh(or addinstall.ps1for Windows)scripts/research/lib/vault.py(theopensubprocess call).env.exampleand README install section
- Formatter: ruff (line length 100, target Python 3.10)
- Imports: standard library first, third-party second, local third (
from .lib import ...) - Type hints on public functions; not required for trivial helpers
- Error handling: translate API errors to plain-English
SystemExitmessages with fix instructions, not stack traces
- Headers: sentence case (
## What it does, not## What It Does) - Code blocks: language tag (
bash,python,yaml) - No trailing whitespace
- One blank line between sections
- Subject line: imperative mood, focus on WHY ("Add /x-pulse command for X trend scanning"), not WHAT ("Added file")
- Body: explain motivation if non-obvious. Wrap at 72 chars.
- Co-author tag if Claude pair-programmed:
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same as commits — imperative + WHY-focused. Examples that ship fast:
- ✅
Add /obsidian-shipped for weekly retrospectives - ✅
Fix /research-deep retry logic when Grok times out - ❌
Updates - ❌
WIP fix
Right now the project has no formal test suite (planned post-v1.0). Until then:
For Python changes:
# Verify imports
uv run python -c "from scripts.research import x_read, x_pulse, research, research_deep, youtube_extract; print('OK')"
# Smoke test a command (requires API keys)
uv run -m scripts.research.x_read "https://x.com/some/post"For slash command changes:
- Symlink your local checkout into
~/.claude/commands/ - Restart Claude Code
- Invoke the command and verify the output matches the AI-first rule
For vault note writes:
- Open the resulting note in Obsidian
- Check the frontmatter is valid YAML
- Verify all
[[wikilinks]]resolve - Confirm the
## For future Claudepreamble is present and accurate
- Fork the repo and create a branch from
main - Make your changes following the AI-first rule and style guide
- Update
SKILL.md,README.md, andCHANGELOG.mdas needed - Run
uv syncto verify dependencies still resolve - Open a PR using the PR template
- Maintain a respectful tone in review discussions
- Address feedback by pushing additional commits (don't force-push during review)
- Once approved, the maintainer will squash-merge
(For maintainers — included so contributors understand the cadence.)
- Merge approved PRs to
main - Update
CHANGELOG.md— move "Unreleased" entries under a new version header with date - Bump version in
pyproject.tomlandCITATION.cff - Tag the release:
git tag v0.X.0 && git push origin v0.X.0 - Create a GitHub release with detailed notes covering: new commands, breaking changes, bug fixes, contributors
- Questions about how to use a command: Discussions Q&A
- Showcase your vault setup: Discussions Show & Tell
- Bugs: bug report form
- Direct contact (private / security): see SECURITY.md (when added) or DM @eugeniu_ghelbur
Contributors are listed in release notes for the version their work shipped in. Significant contributions earn a permanent mention in the README.
Thanks for making this skill better. The vault gets smarter every time someone ships a new command. 🧠