Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins/obsidian/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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"
}
52 changes: 47 additions & 5 deletions plugins/obsidian/README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
27 changes: 24 additions & 3 deletions plugins/obsidian/commands/capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
57 changes: 57 additions & 0 deletions plugins/obsidian/commands/configure.md
Original file line number Diff line number Diff line change
@@ -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
```
207 changes: 207 additions & 0 deletions plugins/obsidian/commands/gmail-digest.md
Original file line number Diff line number Diff line change
@@ -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.