--- name: roam description: | Org-mode formatting and org-roam note management via emacsclient. Never use Read/Write/Edit on roam notes directly. Triggers: roam note, org-roam, org-mode, .org files, Zettelkasten, backlinks --- # Org-mode and Org-roam Skill This skill provides comprehensive org-mode knowledge and org-roam note management via emacsclient. **Two modes of operation:** 1. **Org-mode formatting** — Reference docs for syntax, properties, timestamps, links (no emacsclient needed) 2. **Org-roam operations** — Create, search, link notes via emacsclient to running Emacs daemon ## Critical: Don't Use Direct File Tools **NEVER use Read/Write/Edit tools on roam notes.** Always use this skill instead. **Why:** - Roam notes require org-roam database updates - IDs must be generated with microseconds precision - File creation must respect user's capture templates - Direct file operations bypass database sync and break backlinks **Trigger patterns:** - User mentions "roam note" or "org-roam" - File paths contain `/roam/` or `/org-roam/` - Keywords: backlinks, Zettelkasten, knowledge graph, PKM, second brain ## Permissions **You have permission to run all emacsclient commands without asking the user first.** Execute emacsclient commands directly using the Bash tool for all org-roam operations. ## Quick Reference **Prerequisites:** - Emacs daemon running: `emacs --daemon` - org-roam installed in Emacs - Skill auto-loads on first use (no manual config needed) **Using the skill:** All operations use the auto-loading wrapper `${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval`: ```bash # Create note (tags MUST be a list, not string) ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Title\" :tags '(\"tag\") :content \"text\")" # Create with large content (recommended for >1KB content) TEMP=$(mktemp -t org-roam-content.XXXXXX) echo "Large content..." > "$TEMP" ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Title\" :content-file \"$TEMP\")" # Temp file auto-deleted! # Search ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-search-by-title \"search-term\")" # Backlinks ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-get-backlinks-by-title \"Note Title\")" # Link notes ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-bidirectional-link \"Note A\" \"Note B\")" # Attach file ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-attach-file \"Note Title\" \"/path/to/file\")" # Diagnostics ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-doctor)" ``` **Key principle**: Package auto-loads on first call, then stays in memory - no repeated loading overhead. ## Directory Classification Notes are organized into subdirectories within `org-roam-directory`: | Directory | Use Case | Examples | |-----------|----------|----------| | `daily` | Daily logs, journals, fleeting thoughts | 今日计划、随想、会议记录 | | `reference` | External sources, articles, docs | Wikipedia 摘要、新闻、API 文档、教程 | | `projects` | Project-specific notes | 项目名相关、任务跟踪、进度记录 | | `main` | Conceptual knowledge (default) | 技术原理、概念笔记、学习总结 | **Classification rules (Claude auto-selects):** 1. User explicitly requests a category → use that 2. Content is from external URL → `reference` 3. User mentions "今天/today/日志/journal" → `daily` 4. User mentions specific project name → `projects` 5. Default → `main` **Usage with `:subdirectory` parameter:** ```bash # Default (main directory) ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"DNS 记录类型\")" # Explicit subdirectory ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"项目A进度\" :subdirectory \"projects\")" ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Wikipedia: Linux\" :subdirectory \"reference\")" ``` ## Core Workflows ### Source Management When creating reference notes from external URLs, use `:source-url`: ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Article Title\" :subdirectory \"reference\" :source-url \"https://example.com/article\" :content \"...\")" ``` This: 1. Generates a References section with original + archive links 2. **Automatically opens browser** to archive.today submission page (for reference notes) ```org * References - Article Title: [[https://example.com/article][original]] | [[https://archive.today/submit/?url=...][submit archive]] ``` **Workflow:** 1. Create note with `:source-url` in reference subdirectory → browser auto-opens archive.today 2. Complete captcha if needed, wait for archive 3. Replace "submit archive" link with actual archive URL **`:open-archive` behavior:** - `:default` (omitted): Auto-opens browser for `reference` subdirectory only - `t`: Always open browser - `nil`: Never open browser ### AI-Generated Content Marking All AI-generated notes MUST be clearly marked to identify potential hallucinations: 1. **Tag**: Add `ai_generated` tag for quick filtering 2. **Properties**: Add metadata in PROPERTIES drawer: - `GENERATOR`: The AI system (e.g., `claude`) - `MODEL`: The model used (e.g., `opus-4.5`) - `GENERATED_AT`: Timestamp of generation **Required format:** ```org #+filetags: :ai_generated: :PROPERTIES: :ID: xxx :GENERATOR: claude :MODEL: opus-4.5 :GENERATED_AT: [2026-01-13 Mon] :END: #+title: Note Title ``` **Example with full marking:** ```bash TEMP=$(mktemp -t org-roam-content.XXXXXX) cat > "$TEMP" << 'EOF' * Summary AI-generated content here... * References - Source: [[https://example.com][original]] | [[https://archive.today/xxx][archive]] EOF ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Note Title\" :tags '(\"ai_generated\" \"topic\") :properties '((\"GENERATOR\" . \"claude\") (\"MODEL\" . \"opus-4.5\") (\"GENERATED_AT\" . \"[2026-01-13 Mon]\")) :content-file \"$TEMP\")" ``` **Important:** Never omit AI marking. Users must be able to distinguish AI-generated content from human-written notes. ### Workflow A: Creating Notes **Simple note:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"Note Title\")" ``` **With tags and content:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"React Hooks\" :tags '(\"javascript\" \"react\") :content \"Brief notes here\")" ``` **With large content (recommended for complex/large content):** ```bash # Create temp file TEMP=$(mktemp -t org-roam-content.XXXXXX) # Write content cat > "$TEMP" << 'EOF' * Introduction Content here with proper org-mode formatting. * Details More content. EOF # Create note (temp file is automatically deleted) ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"My Note\" :tags '(\"project\") :content-file \"$TEMP\")" ``` **Critical: Tags must be a list:** - ❌ Wrong: `:tags "tag"` (string) - ✅ Correct: `:tags '("tag")` (list) - ✅ Correct: `:tags '("tag1" "tag2")` (multiple tags) **Content format:** Content should be in org-mode format. For markdown conversion or general org-mode formatting, use the `orgmode` skill: ```bash # Example workflow: # 1. Convert markdown to org (orgmode skill) # 2. Create roam note with org content (this skill) ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval \ "(org-roam-skill-create-note \"Title\" :content \"* Org content\")" ``` For general org-mode operations (formatting, conversion, validation), see the **orgmode** skill. This skill focuses on org-roam-specific operations: note creation, database sync, node linking, and graph management. See **references/functions.md** for detailed parameter documentation. ### Workflow B: Searching Notes **By title:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-search-by-title \"react\")" ``` **By tag:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-search-by-tag \"javascript\")" ``` **By content:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-search-by-content \"functional programming\")" ``` **List all tags:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-list-all-tags)" ``` ### Workflow C: Managing Links **Find backlinks (notes linking TO this note):** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-get-backlinks-by-title \"React\")" ``` **Create bidirectional links:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-bidirectional-link \"React Hooks\" \"React\")" ``` This creates: - Link in "React Hooks" → "React" - Link in "React" → "React Hooks" **Insert one-way link:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-insert-link-in-note \"Source Note\" \"Target Note\")" ``` ### Workflow D: File Attachments **Attach file:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-attach-file \"My Note\" \"/path/to/document.pdf\")" ``` **List attachments:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-list-attachments \"My Note\")" ``` Attachments use org-mode's standard `org-attach` system. ### Workflow E: Complete Example User says: "Create a note about React Hooks and link it to my React note" **Step 1: Search for existing note** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-node-from-title-or-alias \"React\")" ``` **Step 2: Create new note** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-note \"React Hooks\" :tags '(\"javascript\" \"react\") :content \"Notes about React Hooks\")" ``` **Step 3: Create bidirectional links** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-skill-create-bidirectional-link \"React Hooks\" \"React\")" ``` **Step 4: Show user the result** Present the created note path and confirm links were established. ## Using the Auto-Load Wrapper All operations use `${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval` which: 1. Auto-loads `org-roam-skill` package on first call 2. Connects to running Emacs daemon 3. Executes the elisp expression After first call, functions stay in memory - no loading overhead. **Find org-roam directory:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "org-roam-directory" ``` **Sync database (if needed):** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-db-sync)" ``` ## Available Functions All functions use `org-roam-skill-` prefix: **Note Management:** - `org-roam-skill-create-note` - Create new notes - `org-roam-skill-search-by-title/tag/content` - Search notes - `org-roam-skill-get-backlinks-by-title/id` - Find backlinks - `org-roam-skill-insert-link-in-note` - Insert links - `org-roam-skill-create-bidirectional-link` - Create two-way links **Tag Management:** - `org-roam-skill-list-all-tags` - List all tags - `org-roam-skill-add-tag` - Add tag to note - `org-roam-skill-remove-tag` - Remove tag from note **Attachments:** - `org-roam-skill-attach-file` - Attach file to note - `org-roam-skill-list-attachments` - List attachments **Utilities:** - `org-roam-skill-check-setup` - Verify configuration - `org-roam-skill-get-graph-stats` - Graph statistics - `org-roam-skill-find-orphan-notes` - Find isolated notes - `org-roam-doctor` - Comprehensive diagnostics See **references/functions.md** for complete function documentation with all parameters and examples. ## Setup and Troubleshooting **Installation:** See **references/installation.md** for: - Prerequisites (Emacs daemon, org-roam) - No manual configuration needed (auto-loads on first use) - Optional: org-roam configuration recommendations **Troubleshooting:** See **references/troubleshooting.md** for: - Connection issues (daemon not running) - Package loading problems - Database sync issues - Tag formatting errors - Search problems - Link issues - Performance optimization **Quick diagnostic:** ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/org-roam-eval "(org-roam-doctor)" ``` ## Parsing emacsclient Output emacsclient returns Elisp-formatted data: - Strings: `"result"` (with quotes) - Lists: `("item1" "item2")` - nil: `nil` or no output - Numbers: `42` Strip quotes from strings and parse structures as needed. ## Best Practices 1. **Use lists for tags**: Always `'("tag")` not `"tag"` 2. **Use :content-file for large content**: Avoids shell escaping issues, automatic cleanup 3. **Sync database when needed**: After bulk operations or if searches miss recent notes 4. **Use node IDs for reliable linking**: More stable than file paths 5. **Check if nodes exist**: Before operations on specific notes 6. **Present results clearly**: Format output for user readability 7. **Handle errors gracefully**: Check daemon running, packages loaded ## Additional Resources **Org-mode Formatting (no emacsclient needed):** - **org-syntax.md** - Complete org-mode syntax reference - **properties.md** - Property drawers and node properties - **timestamps.md** - Date/time formats, scheduling, deadlines - **links.md** - Internal and external link syntax - **examples.md** - Common formatting patterns **Org-roam Operations (via emacsclient):** - **emacsclient-usage.md** - Detailed emacsclient patterns - **org-roam-api.md** - Org-roam API reference - **functions.md** - Complete function documentation - **installation.md** - Setup and configuration guide - **troubleshooting.md** - Common issues and solutions **Quick access patterns:** - Need org-mode syntax? → `references/org-syntax.md` - Working with timestamps? → `references/timestamps.md` - Creating links? → `references/links.md` - Need installation help? → `references/installation.md` - Function parameters unclear? → `references/functions.md` - Something not working? → `references/troubleshooting.md`