diff --git a/plugins/obsidian/.claude-plugin/plugin.json b/plugins/obsidian/.claude-plugin/plugin.json index bb9be07..cc4762e 100644 --- a/plugins/obsidian/.claude-plugin/plugin.json +++ b/plugins/obsidian/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "arevlo:obsidian", - "description": "Capture screenshots and context to Obsidian Zettelkasten vault as fragment notes. Save external links to note tables.", - "version": "1.2.1" + "description": "Capture screenshots and context to Obsidian Zettelkasten vault as fragment notes. Save external links to note tables. Generate Gmail digest summaries.", + "version": "1.4.0" } diff --git a/plugins/obsidian/README.md b/plugins/obsidian/README.md index 364dfba..ddc9878 100644 --- a/plugins/obsidian/README.md +++ b/plugins/obsidian/README.md @@ -1,6 +1,6 @@ # Obsidian Capture Plugin -Capture screenshots and context directly to your Obsidian Zettelkasten vault as fragment notes. +Capture screenshots and context directly to your Obsidian Zettelkasten vault as fragment notes. Save external links to note tables. Generate Gmail digest summaries. ## Commands @@ -92,14 +92,54 @@ The command creates/updates a table in your note with this structure: | Constitutional AI Research Paper | #research #alignment #source/anthropic | [Constitutional AI Research Paper](https://anthropic.com/research/constitutional-ai) | Foundational paper on RLHF with AI feedback | ``` -## Configuration +### `/arevlo:obsidian:gmail-digest` + +Open Gmail in Chrome, read all unread emails, categorize them, and save a bucketed digest to your Obsidian vault. -The plugin expects your Obsidian vault at: +**Usage:** ``` -/Users/arevlo/Library/Mobile Documents/com~apple~CloudDocs/zk +/arevlo:obsidian:gmail-digest ``` -To change this, edit the `VAULT_PATH` in `commands/capture.md`. +**What it does:** +1. Opens Gmail in Chrome filtered to unread emails +2. Reads each unread email (opening them marks as read) +3. Categorizes emails into buckets: + - **Action Required** — needs a response or task + - **Calendar & Scheduling** — meeting invites, schedule changes + - **Conversations** — ongoing threads/replies + - **FYI / Informational** — newsletters, notifications, updates + - **Automated / System** — receipts, alerts, service notifications +4. Generates a structured markdown digest +5. Saves to `{digest_output_path}/gmail-digest-YYYY-MM-DD.md` +6. Shows summary of processed emails and categories + +**Example output file:** `gmail-digest-2026-02-07.md` (saved to your configured `digest_output_path`) + +**Notes:** +- Running multiple times per day appends a counter (e.g., `gmail-digest-2026-02-07-2.md`) +- Requires Chrome with the Claude in Chrome extension +- Emails are marked as read by being opened during processing + +### `/arevlo:obsidian:configure` + +Set up or update the Obsidian plugin configuration (vault path, digest output path). + +**Usage:** +``` +/arevlo:obsidian:configure +``` + +## Configuration + +On first use, any command will prompt you to configure your paths. Configuration is stored in `~/.claude/obsidian-plugin.json`: + +| Field | Used By | Description | +|-------|---------|-------------| +| `vault_path` | `/capture`, `/save-link` | Absolute path to your Obsidian vault | +| `digest_output_path` | `/gmail-digest` | Absolute path for Gmail digest files | + +To reconfigure, run `/arevlo:obsidian:configure` or edit `~/.claude/obsidian-plugin.json` directly. ## Installation @@ -147,5 +187,7 @@ Use `mcp__obsidian-zettelkasten__process_fragment` to convert fragments to primi ## Version History +- **1.4.0** - Made paths configurable via `~/.claude/obsidian-plugin.json`; added `/arevlo:obsidian:configure` command +- **1.3.0** - Added `/arevlo:obsidian:gmail-digest` command for Gmail digest summaries - **1.2.0** - Added `/arevlo:obsidian:save-link` command for saving external links to notes - **1.0.0** - Initial release with screenshot capture to fragment notes diff --git a/plugins/obsidian/commands/capture.md b/plugins/obsidian/commands/capture.md index 1f71b14..d9faa7f 100644 --- a/plugins/obsidian/commands/capture.md +++ b/plugins/obsidian/commands/capture.md @@ -21,10 +21,31 @@ When you share a screenshot (from Slack, Figma, browser, etc.) along with option ## Configuration -**Obsidian vault path:** `/Users/arevlo/Library/Mobile Documents/com~apple~CloudDocs/zk` +Configuration is stored in `~/.claude/obsidian-plugin.json`. The `vault_path` field is used for fragment captures. ## Steps +### 0. Load Configuration + +Before doing anything else, read the configuration file: + +1. Use the `Read` tool to read `~/.claude/obsidian-plugin.json` +2. **If the file does not exist:** + - Inform the user: "No Obsidian plugin configuration found. Let's set it up." + - Use `AskUserQuestion` to ask for their Obsidian vault path (absolute path, no `~`) + - Use `AskUserQuestion` to ask for their digest output directory (absolute path, no `~`) + - Use `Bash` to create the config file: + ```bash + mkdir -p ~/.claude && cat > ~/.claude/obsidian-plugin.json << 'ENDCONFIG' + { + "vault_path": "{user's vault path}", + "digest_output_path": "{user's digest path}" + } + ENDCONFIG + ``` + - Continue with the values provided +3. **If the file exists:** Parse the JSON and extract `vault_path` for use in subsequent steps + ### 1. Gather Information First **Before doing any file operations**, collect all the information needed: @@ -106,8 +127,8 @@ echo "━━━━━━━━━━━━━━━━━━━━━━━━ Then continue with the copy operation: ```bash -# Set vault path and fragment folder -VAULT_PATH="/Users/arevlo/Library/Mobile Documents/com~apple~CloudDocs/zk" +# Set vault path from config (loaded in Step 0) and fragment folder +VAULT_PATH="{vault_path from config}" FRAGMENT_FOLDER="{category}/fragments" # Create _attachments folder if needed diff --git a/plugins/obsidian/commands/configure.md b/plugins/obsidian/commands/configure.md new file mode 100644 index 0000000..3e5d99d --- /dev/null +++ b/plugins/obsidian/commands/configure.md @@ -0,0 +1,57 @@ +--- +description: Configure Obsidian plugin vault paths +allowed-tools: Read,Write,AskUserQuestion +--- + +Configure or update the Obsidian plugin paths used by `/capture`, `/save-link`, and `/gmail-digest`. + +## What this does + +Sets up `~/.claude/obsidian-plugin.json` with your personal vault and output paths so all Obsidian plugin commands work correctly. + +## Steps + +### 1. Check for Existing Configuration + +Use the `Read` tool to read `~/.claude/obsidian-plugin.json`. + +- **If the file exists:** Show the current configuration values to the user. +- **If the file does not exist:** Inform the user that no configuration exists yet. + +### 2. Ask for Vault Path + +Use `AskUserQuestion` to ask: +- Question: "What is the absolute path to your Obsidian vault?" +- If updating, show the current value as context in the question +- Remind the user to use an absolute path (no `~`) + +### 3. Ask for Digest Output Path + +Use `AskUserQuestion` to ask: +- Question: "What is the absolute path for Gmail digest output files?" +- If updating, show the current value as context in the question +- Remind the user to use an absolute path (no `~`) + +### 4. Save Configuration + +Use the `Write` tool to save the config to `~/.claude/obsidian-plugin.json`: + +```json +{ + "vault_path": "{user's vault path}", + "digest_output_path": "{user's digest path}" +} +``` + +### 5. Confirm + +Show the saved configuration: + +``` +Obsidian plugin configured! + + vault_path: {vault_path} + digest_output_path: {digest_output_path} + +Config saved to: ~/.claude/obsidian-plugin.json +``` diff --git a/plugins/obsidian/commands/gmail-digest.md b/plugins/obsidian/commands/gmail-digest.md new file mode 100644 index 0000000..afbe444 --- /dev/null +++ b/plugins/obsidian/commands/gmail-digest.md @@ -0,0 +1,207 @@ +--- +description: Analyze unread Gmail emails and create a bucketed digest in Obsidian vault +allowed-tools: mcp__claude-in-chrome__tabs_context_mcp,mcp__claude-in-chrome__tabs_create_mcp,mcp__claude-in-chrome__navigate,mcp__claude-in-chrome__read_page,mcp__claude-in-chrome__javascript_tool,mcp__claude-in-chrome__computer,Write,Bash,AskUserQuestion,Read +--- + +Open Gmail in Chrome, read all unread emails, categorize them into bucketed summaries, save as a dated markdown file in the Obsidian vault, and mark emails as read. + +## Configuration + +Configuration is stored in `~/.claude/obsidian-plugin.json`. The `digest_output_path` field is used for the output directory. + +**Output filename:** `gmail-digest-YYYY-MM-DD.md` (appends counter if file exists: `gmail-digest-2026-02-07-2.md`) + +## Steps + +### 0. Load Configuration + +Before doing anything else, read the configuration file: + +1. Use the `Read` tool to read `~/.claude/obsidian-plugin.json` +2. **If the file does not exist:** + - Inform the user: "No Obsidian plugin configuration found. Let's set it up." + - Use `AskUserQuestion` to ask for their Obsidian vault path (absolute path, no `~`) + - Use `AskUserQuestion` to ask for their digest output directory (absolute path, no `~`) + - Use `Bash` to create the config file: + ```bash + mkdir -p ~/.claude && cat > ~/.claude/obsidian-plugin.json << 'ENDCONFIG' + { + "vault_path": "{user's vault path}", + "digest_output_path": "{user's digest path}" + } + ENDCONFIG + ``` + - Continue with the values provided +3. **If the file exists:** Parse the JSON and extract `digest_output_path` for use in subsequent steps + +### 1. Open Gmail Unread View + +Use `mcp__claude-in-chrome__tabs_create_mcp` to create a new tab, then `mcp__claude-in-chrome__navigate` to: + +``` +https://mail.google.com/mail/u/0/#search/is%3Aunread +``` + +Wait for the page to load fully. + +### 2. Read the Unread Email List + +Use `mcp__claude-in-chrome__read_page` to extract the list of unread emails visible on the page. Capture: +- Sender name +- Subject line +- Snippet/preview text +- Approximate time received + +If there are **no unread emails**, skip to Step 7 and inform the user: +``` +No unread emails found. Nothing to digest! +``` + +### 3. Deep Read Each Email + +For each unread email in the list: + +1. **Click into the email** using `mcp__claude-in-chrome__computer` (click on the email row). Opening an email in Gmail **automatically marks it as read**. +2. **Read the full content** using `mcp__claude-in-chrome__read_page` to get the complete email body, sender details, and any attachments info. +3. **Navigate back** to the unread list. Use `mcp__claude-in-chrome__navigate` to go back to `https://mail.google.com/mail/u/0/#search/is%3Aunread` (the list will now show remaining unread emails). +4. **Repeat** until all unread emails have been read. + +**Pagination:** If after reading all visible emails the unread list still shows more emails (pagination), continue reading those as well. + +**Important:** Keep a running list of all email data collected. For each email, store: +- Sender (name and email) +- Subject +- Date/time +- Full body content (or meaningful summary for very long emails) +- Whether it's part of a thread +- Any action items or requests mentioned + +### 4. Analyze & Categorize + +Bucket every email into exactly one of these categories: + +- **Action Required** — Emails needing a response, decision, or task from the user +- **Calendar & Scheduling** — Meeting invites, schedule changes, RSVPs +- **Conversations** — Ongoing threads, replies, discussions +- **FYI / Informational** — Newsletters, announcements, product updates, notifications +- **Automated / System** — Receipts, shipping confirmations, alerts, service notifications, automated reports + +For each email, determine: +- **Category** (one of the above) +- **Key takeaway** (1-2 sentence summary of what matters) +- **Urgency** (if applicable, especially for Action Required items) + +### 5. Generate Markdown + +Build the digest markdown file with this structure: + +```markdown +--- +date: YYYY-MM-DD +type: gmail-digest +emails_processed: {count} +--- + +# Gmail Digest — {Mon DD, YYYY} + +> {count} unread emails processed and marked as read. + +## Action Required ({count}) + +### {Subject} — {Sender Name} +{Key takeaway / summary. Include urgency or deadlines if mentioned.} + +... + +## Calendar & Scheduling ({count}) + +### {Subject} — {Sender Name} +{Key takeaway / summary.} + +... + +## Conversations ({count}) + +### {Subject} — {Sender Name} +{Key takeaway / summary. Note thread context if relevant.} + +... + +## FYI / Informational ({count}) + +### {Subject} — {Sender Name} +{Key takeaway / summary.} + +... + +## Automated / System ({count}) + +### {Subject} — {Sender Name} +{Key takeaway / summary.} + +... +``` + +**Rules:** +- Only include category sections that have emails. Skip empty categories entirely. +- Order categories by importance: Action Required first, Automated/System last. +- Each email entry should be concise — 1-3 sentences max for the summary. +- Use the sender's display name, not their email address. +- Format dates in the header as "Feb 7, 2026" style. + +### 6. Save the File + +Determine the filename: + +```bash +DATE=$(date +%Y-%m-%d) +OUTPUT_DIR="{digest_output_path from config}" +BASE="${OUTPUT_DIR}/gmail-digest-${DATE}" +FILE="${BASE}.md" + +# If file already exists, append a counter +if [ -f "$FILE" ]; then + COUNTER=2 + while [ -f "${BASE}-${COUNTER}.md" ]; do + COUNTER=$((COUNTER + 1)) + done + FILE="${BASE}-${COUNTER}.md" +fi + +echo "$FILE" +``` + +Use the `Write` tool to save the markdown content to the resolved file path. + +### 7. Confirm to User + +**If no unread emails were found** (skipped from Step 2), just inform the user: + +``` +No unread emails found. Nothing to digest! +``` + +**If emails were processed**, show a summary: + +``` +Gmail Digest Complete + + Emails processed: {count} + Categories: + - Action Required: {n} + - Calendar & Scheduling: {n} + - Conversations: {n} + - FYI / Informational: {n} + - Automated / System: {n} + + Saved to: {digest_output_path}/gmail-digest-YYYY-MM-DD.md + All emails marked as read. +``` + +## Notes + +- **Reading = marking as read:** Opening each email in Gmail's web UI automatically marks it as read. No additional action is needed to mark emails as read. +- **Long emails:** For very long emails (marketing newsletters, legal notices), summarize the key point rather than capturing everything. +- **Attachments:** Note if an email has attachments but don't attempt to download them. +- **Errors:** If Gmail fails to load or Chrome is unresponsive, inform the user and suggest they check their browser/internet connection. +- **Multiple runs per day:** The filename counter logic handles this gracefully.