Merge branch 'main' into feature/add-download-and-pr-commands

This commit is contained in:
Noah Brier
2025-09-17 15:52:28 -04:00
34 changed files with 7006 additions and 747 deletions
+2 -7
View File
@@ -37,14 +37,9 @@
"ws": "weekly-synthesis"
},
"preferences": {
"primary_folders": [
"00_Inbox",
"01_Projects",
"02_Areas",
"03_Resources"
],
"primary_folders": ["00_Inbox", "01_Projects", "02_Areas", "03_Resources"],
"template_folder": "06_Metadata/Templates",
"archive_after_days": 30,
"default_note_location": "00_Inbox"
}
}
}
+20 -1
View File
@@ -5,38 +5,53 @@ Pre-configured commands to enhance your Claude Code + Obsidian workflow.
## Available Commands
### 🤔 thinking-partner
Engage Claude as a thinking partner for exploring complex problems.
```
/thinking-partner
```
Best for: Brainstorming, problem exploration, developing ideas
### 📥 inbox-processor
Process and organize items in your Inbox folder.
```
/inbox-processor
```
Best for: Weekly inbox cleanup, organizing captures
### 🔍 research-assistant
Conduct thorough research on any topic using your vault.
```
/research-assistant
```
Best for: Deep dives, literature reviews, knowledge synthesis
### 📅 daily-review
End-of-day review to capture progress and plan tomorrow.
```
/daily-review
```
Best for: Daily shutdown ritual, reflection
### 📊 weekly-synthesis
Create a comprehensive synthesis of the week's work.
```
/weekly-synthesis
```
Best for: Weekly reviews, pattern recognition
## Creating Custom Commands
@@ -52,16 +67,19 @@ Best for: Weekly reviews, pattern recognition
## Using Commands
### Method 1: Direct (in Claude Code)
```
/[command-name]
```
### Method 2: Reference in Chat
```
Use the thinking-partner command to help me explore [topic]
```
### Method 3: Manual
```
Follow the instructions in .claude/commands/[command].md
```
@@ -76,6 +94,7 @@ Follow the instructions in .claude/commands/[command].md
## Command Ideas
Consider creating commands for:
- Project retrospectives
- Meeting notes processing
- Book notes extraction
@@ -84,4 +103,4 @@ Consider creating commands for:
- Learning path creation
- Decision analysis
Remember: The best commands emerge from your actual workflows.
Remember: The best commands emerge from your actual workflows.
+33 -13
View File
@@ -1,18 +1,22 @@
---
description: Add or update YAML frontmatter properties to enhance note organization
description:
Add or update YAML frontmatter properties to enhance note organization
argument-hint: [file or folder path]
allowed-tools: Read, Write, Edit, Glob
---
You will analyze Obsidian notes and add intelligent YAML frontmatter properties to enhance organization and discoverability.
You will analyze Obsidian notes and add intelligent YAML frontmatter properties
to enhance organization and discoverability.
## Input
- Path: ${1} (file or folder to process)
- Current date: !`date +%Y-%m-%d`
## Your Task
### Step 1: Identify Notes to Process
```bash
# If single file
Read the specified file
@@ -24,6 +28,7 @@ Find all .md files in folder
### Step 2: Analyze Note Content
For each note, examine:
- Main topics and themes
- Note type (meeting, daily, reference, project)
- Key entities (people, projects, dates)
@@ -35,22 +40,24 @@ For each note, examine:
#### Standard Properties by Note Type
**Meeting Notes:**
```yaml
---
title: [Descriptive meeting title]
date: YYYY-MM-DD
type: meeting
attendees: ["Person 1", "Person 2"]
attendees: ['Person 1', 'Person 2']
project: Project Name
tags: [meeting, project-name]
action_items:
- "Action item 1"
- "Action item 2"
action_items:
- 'Action item 1'
- 'Action item 2'
status: complete
---
```
**Daily Notes:**
```yaml
---
title: Daily Note - YYYY-MM-DD
@@ -58,12 +65,13 @@ date: YYYY-MM-DD
type: daily-note
tags: [daily]
highlights:
- "Key event or thought"
- 'Key event or thought'
mood: productive
---
```
**Reference/Article Notes:**
```yaml
---
title: [Article or concept title]
@@ -77,13 +85,14 @@ key_concepts: [concept1, concept2]
```
**Project Notes:**
```yaml
---
title: [Project Name - Component]
type: project
status: in-progress
deadline: YYYY-MM-DD
stakeholders: ["Person 1", "Team 2"]
stakeholders: ['Person 1', 'Team 2']
tags: [project, area]
priority: high
---
@@ -92,6 +101,7 @@ priority: high
### Step 4: Apply Properties
For each note:
1. Check for existing frontmatter
2. Merge new properties (don't duplicate)
3. Fix any deprecated formats:
@@ -106,22 +116,23 @@ For each note:
# Format:
---
property: value
list_property: ["item1", "item2"]
list_property: ['item1', 'item2']
date_property: YYYY-MM-DD
linked_property: "[[Note Name]]"
linked_property: '[[Note Name]]'
---
[Original content]
```
## Property Guidelines
### Naming Conventions
- Use lowercase with underscores: `date_created`, `action_items`
- Be consistent with existing vault patterns
- Prefer clear over clever names
### Value Types
- **Text**: Simple strings, use quotes for links
- **List**: Arrays for multiple values
- **Date**: ISO format (YYYY-MM-DD)
@@ -129,6 +140,7 @@ linked_property: "[[Note Name]]"
- **Checkbox**: For boolean states
### Quality Checks
- ✅ Valid YAML syntax
- ✅ No duplicate properties
- ✅ Appropriate property types
@@ -138,18 +150,23 @@ linked_property: "[[Note Name]]"
## Special Cases
### Untitled Notes
Generate title from:
1. First heading if exists
2. First paragraph summary
3. Main topic/concept discussed
### Bulk Processing
When processing folders:
- Maintain consistency across similar notes
- Use same property names for same concepts
- Report summary of changes made
### Existing Properties
- Preserve valid existing properties
- Update deprecated formats
- Merge new properties carefully
@@ -158,17 +175,19 @@ When processing folders:
## Examples
### Before:
```markdown
Had a great meeting with the team about Q1 planning...
```
### After:
```markdown
---
title: Q1 Planning Team Meeting
date: 2025-09-02
type: meeting
attendees: ["Team"]
attendees: ['Team']
project: Q1 Planning
tags: [meeting, planning, q1-2025]
status: complete
@@ -177,4 +196,5 @@ status: complete
Had a great meeting with the team about Q1 planning...
```
Remember: Properties should enhance organization, not clutter. Only add what provides value for finding and connecting notes.
Remember: Properties should enhance organization, not clutter. Only add what
provides value for finding and connecting notes.
+2 -4
View File
@@ -60,9 +60,7 @@ Brief description of what this command does.
## Example Usage
\`\`\`
claude run [command-name] [arguments]
\`\`\`
\`\`\` claude run [command-name] [arguments] \`\`\`
```
## Best Practices
@@ -74,4 +72,4 @@ claude run [command-name] [arguments]
- Specify output format
- List needed tools in frontmatter
Let me help you create your command!
Let me help you create your command!
+9 -2
View File
@@ -32,30 +32,37 @@ Create or update a daily note with:
# Daily Review - [Date]
## Accomplished
- ✓ [Completed item 1]
- ✓ [Completed item 2]
## Progress Made
- [Project/Area]: [What moved forward]
- [Project/Area]: [What moved forward]
## Insights
- [Key realization or connection]
- [Important learning]
## Blocked/Stuck
- [What didn't progress and why]
## Discovered Questions
- [New question that emerged]
- [Thing to research]
## Tomorrow's Focus
1. [Priority 1]
2. [Priority 2]
2. [Priority 2]
3. [Priority 3]
## Open Loops
- [ ] [Thing to remember]
- [ ] [Person to follow up with]
- [ ] [Idea to develop]
@@ -66,4 +73,4 @@ Create or update a daily note with:
- Move completed project tasks to archive
- Update project status notes
- Link related discoveries
- Flag items needing attention
- Flag items needing attention
+17 -6
View File
@@ -10,33 +10,39 @@ Remove AI-generated patterns and restore natural human voice to your writing.
## Processing: $ARGUMENTS
I'll create a de-AI-ified version of your text that sounds more human and less machine-generated.
I'll create a de-AI-ified version of your text that sounds more human and less
machine-generated.
## What Gets Removed
### 1. Overused Transitions
- "Moreover," "Furthermore," "Additionally," "Nevertheless"
- Excessive "However" usage
- "While X, Y" openings
### 2. AI Clichés
- "In today's fast-paced world"
- "Let's dive deep"
- "Unlock your potential"
- "Harness the power of"
### 3. Hedging Language
- "It's important to note"
- "It's worth mentioning"
- Vague quantifiers: "various," "numerous," "myriad"
### 4. Corporate Buzzwords
- "utilize" → "use"
- "facilitate" → "help"
- "optimize" → "improve"
- "leverage" → "use"
### 5. Robotic Patterns
- Rhetorical questions followed by immediate answers
- Obsessive parallel structures
- Always using exactly three examples
@@ -45,12 +51,14 @@ I'll create a de-AI-ified version of your text that sounds more human and less m
## What Gets Added
### Natural Voice
- Varied sentence lengths
- Conversational tone
- Direct statements
- Specific examples
### Human Rhythm
- Natural transitions
- Confident assertions
- Personal perspective
@@ -66,16 +74,19 @@ I'll create a de-AI-ified version of your text that sounds more human and less m
## Output
You'll get:
- A new file with natural human voice
- Change log showing what was fixed
- List of places needing specific examples
## Example Transformations
**Before (AI):**
"In today's rapidly evolving digital landscape, it's crucial to understand that leveraging AI effectively isn't just about utilizing cutting-edge technology—it's about harnessing its transformative potential to unlock unprecedented opportunities."
**Before (AI):** "In today's rapidly evolving digital landscape, it's crucial to
understand that leveraging AI effectively isn't just about utilizing
cutting-edge technology—it's about harnessing its transformative potential to
unlock unprecedented opportunities."
**After (Human):**
"AI works best when you use it for specific tasks. Focus on what it does well: writing code, analyzing data, and answering questions."
**After (Human):** "AI works best when you use it for specific tasks. Focus on
what it does well: writing code, analyzing data, and answering questions."
Let me de-AI-ify your text!
Let me de-AI-ify your text!
+5 -2
View File
@@ -1,6 +1,7 @@
# Inbox Processor
Help organize and process items in the 00_Inbox folder according to the PARA method.
Help organize and process items in the 00_Inbox folder according to the PARA
method.
## Task
@@ -23,6 +24,7 @@ Review all notes in `00_Inbox/` and help categorize them:
- **→ Delete**: No value, redundant, or temporary
4. **Suggest Actions**
```
File: [filename]
Type: [detected type]
@@ -39,6 +41,7 @@ Review all notes in `00_Inbox/` and help categorize them:
## Output Format
Provide a clear action plan:
1. Items to move (with destinations)
2. Items to combine or link
3. Items to delete
@@ -48,4 +51,4 @@ Provide a clear action plan:
- Some items legitimately belong in the Inbox (daily notes, quick captures)
- Don't over-organize - sometimes "good enough" is perfect
- Look for opportunities to connect ideas, not just file them
- Look for opportunities to connect ideas, not just file them
+188 -115
View File
@@ -1,17 +1,22 @@
---
name: init-bootstrap
description: Interactive setup wizard that helps new users create a personalized CLAUDE.md file based on their Obsidian workflow preferences
description:
Interactive setup wizard that helps new users create a personalized CLAUDE.md
file based on their Obsidian workflow preferences
allowed-tools: [Read, Write, MultiEdit, Bash, Task]
argument-hint: "(optional) path to existing vault or 'new' for fresh setup"
---
# Initialize Bootstrap Configuration
This command helps you create a personalized CLAUDE.md configuration file by asking questions about your Obsidian workflow and preferences.
This command helps you create a personalized CLAUDE.md configuration file by
asking questions about your Obsidian workflow and preferences.
## Task
Read the CLAUDE-BOOTSTRAP.md template and interactively gather information about the user's:
Read the CLAUDE-BOOTSTRAP.md template and interactively gather information about
the user's:
- Existing vault structure (if any)
- Workflow preferences
- Note-taking style
@@ -32,9 +37,12 @@ Then generate a customized CLAUDE.md file tailored to their needs.
- Verify core dependencies are installed
- Check git status:
- If no .git folder: Initialize git repository
- If has remote origin: Remove it to disconnect from claudesidian
- If has remote origin: Ask about development work
- Personal vault: Remove origin and .github folder
- Contributing: Keep origin and workflows intact
- If clean local repo: Ready to go
- Don't create folders yet - wait until after asking about organization method
- Don't create folders yet - wait until after asking about organization
method
2. **Check Existing Configuration**
- Look for existing CLAUDE.md
@@ -44,8 +52,10 @@ Then generate a customized CLAUDE.md file tailored to their needs.
3. **Gather Vault Information**
- Search common locations for existing Obsidian vaults (.obsidian folder)
- Check: ~/Documents, ~/Desktop, home directory, current directory parent
- If found, ask: "Found Obsidian vault at [path]. Is this the vault you want to import?"
- Count files correctly: `find [path] -type f -name "*.md" | wc -l` (no depth limit)
- If found, ask: "Found Obsidian vault at [path]. Is this the vault you want
to import?"
- Count files correctly: `find [path] -type f -name "*.md" | wc -l` (no depth
limit)
- Show vault size: `du -sh [path]`
- If confirmed, analyze vault structure:
- Run `tree -L 3 -d [path]` to see folder hierarchy
@@ -59,19 +69,22 @@ Then generate a customized CLAUDE.md file tailored to their needs.
4. **Ask Configuration Questions**
- "What's your name?" (for personalization)
- "Would you like me to research your public work to better understand your context?"
- "Would you like me to research your public work to better understand your
context?"
- If yes: Search for information
- ALWAYS show findings and ask "Is this correct?" for confirmation
- If multiple people found, list them numbered for selection
- If wrong person, offer to search again or skip
- Save relevant context about their work, writing style, areas of expertise
- "Do you follow the PARA method or have a different organization system?"
- "What are your main use cases? (research, writing, project management, knowledge base, daily notes)"
- "What are your main use cases? (research, writing, project management,
knowledge base, daily notes)"
**If using PARA, ask specific setup questions:**
[PARA Method by Tiago Forte](https://fortelabs.com/blog/para/)
- "What active projects are you working on?" (Create folders in 01_Projects)
- "What areas of responsibility do you maintain?" (e.g., Work, Health, Finance, Family)
- "What areas of responsibility do you maintain?" (e.g., Work, Health,
Finance, Family)
- "What topics do you research frequently?" (Set up in 03_Resources)
- "Any projects you recently completed?" (Can archive with summaries)
@@ -89,20 +102,30 @@ Then generate a customized CLAUDE.md file tailored to their needs.
5. **Optional Tool Setup**
**Gemini Vision (already included)**
- Ask: "Gemini Vision is already included for analyzing images, PDFs, and videos. Would you like to activate it? (yes/no/later)"
- Explain: "You just need a free API key from Google. This lets Claude analyze any visual content in your vault."
- If later: "No problem! You can set it up anytime by running `/setup-gemini`"
- Ask: "Gemini Vision is already included for analyzing images, PDFs, and
videos. Would you like to activate it? (yes/no/later)"
- Explain: "You just need a free API key from Google. This lets Claude
analyze any visual content in your vault."
- If later: "No problem! You can set it up anytime by running
`/setup-gemini`"
- If yes:
- Guide to get API key from https://aistudio.google.com/apikey (free, takes 30 seconds)
- Guide to get API key from https://aistudio.google.com/apikey (free, takes
30 seconds)
- Help add to shell profile (.zshrc, .bashrc, etc.)
- Run `claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs`
- Run
`claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs`
- Configure .mcp.json with API key
- Test the connection with a sample command
**Firecrawl (already included)**
- Ask: "Firecrawl is included for web research. Would you like to set it up? (yes/no/later)"
- Explain: "This is a game-changer for research! When you find an article or website, you can save it directly to your vault as markdown - preserving the content forever, making it searchable, and letting Claude analyze it. Perfect for building a research library."
- Example: "Just tell Claude: 'Save this article to my vault: [URL]' and it's done!"
- Ask: "Firecrawl is included for web research. Would you like to set it up?
(yes/no/later)"
- Explain: "This is a game-changer for research! When you find an article or
website, you can save it directly to your vault as markdown - preserving
the content forever, making it searchable, and letting Claude analyze it.
Perfect for building a research library."
- Example: "Just tell Claude: 'Save this article to my vault: [URL]' and it's
done!"
- If later: "You can set it up anytime by running `/setup-firecrawl`"
- If yes:
- Guide to get API key from https://firecrawl.dev (free tier available)
@@ -120,7 +143,11 @@ Then generate a customized CLAUDE.md file tailored to their needs.
"companies": ["Variance", "Percolate"],
"roles": ["Co-founder", "Writer"],
"publications": ["Why Is This Interesting?", "every.to"],
"expertise": ["Developer tools", "Marketing tech", "Systems thinking"],
"expertise": [
"Developer tools",
"Marketing tech",
"Systems thinking"
],
"interests": ["AI for thinking", "Note-taking systems", "Creativity"]
},
"profileSources": [
@@ -162,7 +189,8 @@ Then generate a customized CLAUDE.md file tailored to their needs.
7. **Import Existing Vault (if applicable)**
- If user has existing vault:
- Create OLD_VAULT folder: `mkdir OLD_VAULT`
- Copy entire vault preserving structure: `cp -r [vault-path]/* ./OLD_VAULT/`
- Copy entire vault preserving structure:
`cp -r [vault-path]/* ./OLD_VAULT/`
- Copy Obsidian configuration: `cp -r [vault-path]/.obsidian ./`
- Check for and copy other important files:
- `.trash/` (Obsidian's trash folder)
@@ -170,7 +198,8 @@ Then generate a customized CLAUDE.md file tailored to their needs.
- Any workspace files: `.obsidian.vimrc`, etc.
- Skip copying: `.git/` (they'll have their own), `.claude/` (using ours)
- Show summary: "Imported your vault to OLD_VAULT/ (X files, Y folders)"
- Explain: "Your original structure is preserved in OLD_VAULT. You can gradually migrate files to the PARA folders as needed."
- Explain: "Your original structure is preserved in OLD_VAULT. You can
gradually migrate files to the PARA folders as needed."
8. **Create Supporting Files**
- Generate initial folder structure if new vault
@@ -193,22 +222,22 @@ Then generate a customized CLAUDE.md file tailored to their needs.
- Verify git is tracking files correctly
10. **Provide Next Steps**
- Summary of what was created and configured
- Quick start guide specific to their setup
- List of available commands they can use
- Test commands to verify everything works
- Suggestions for first tasks based on their use cases
- How to modify configuration later
- Summary of what was created and configured
- Quick start guide specific to their setup
- List of available commands they can use
- Test commands to verify everything works
- Suggestions for first tasks based on their use cases
- How to modify configuration later
## Example Output
```markdown
# Your Obsidian Vault Configuration
Generated on: [Run `date +"%B %d, %Y"` to get current date]
Last updated: [Same date]
Based on your preferences for: [main use cases]
Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
Generated on: [Run `date +"%B %d, %Y"` to get current date] Last updated: [Same
date] Based on your preferences for: [main use cases] Setup completed with: ✅
Dependencies ✅ Folder structure ✅ Git initialized
## Your Custom Folder Structure
@@ -217,12 +246,15 @@ Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
## Your Workflows
### Daily Routine
[Based on their answers]
### Project Management
[Their specific approach]
### Research Method (Noah Brier Style)
- Capture everything you read
- Let important ideas naturally resurface
- Start with writing to test understanding
@@ -230,20 +262,24 @@ Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
- [Learn more from Noah's system](https://every.to/superorganizers/ceo-by-day-internet-sleuth-by-night-267452)
### Weekly Review Ritual
[If enabled: Every Thursday at 4pm, review all projects]
## Your Preferences
### File Naming
- Pattern: [their convention]
- Examples: [specific examples]
### Tools & Scripts
[Relevant scripts for their workflow]
## MCP Servers (if configured)
### Gemini Vision
- Status: ✅ Configured and tested
- API Key: Set in .mcp.json
- Test with: `Use gemini-vision to analyze [image path]`
@@ -251,11 +287,13 @@ Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
## Available Commands
### Vault Management
- `pnpm vault:stats` - Show vault statistics
- `pnpm attachments:list` - List unprocessed attachments
- `pnpm attachments:organized` - Count organized files
### Claude Commands
- `claude run thinking-partner` - Collaborative thinking mode
- `claude run daily-review` - Review your day
- `claude run init-bootstrap` - Re-run this setup
@@ -269,21 +307,20 @@ Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
## Pro Tips from Research Masters
- **Be a token maximalist**: Provide lots of context to Claude
- **Writing scales**: Document everything for future reference ([Noah Brier](https://every.to/superorganizers/ceo-by-day-internet-sleuth-by-night-267452))
- **Writing scales**: Document everything for future reference
([Noah Brier](https://every.to/superorganizers/ceo-by-day-internet-sleuth-by-night-267452))
- **Trust emergence**: Important ideas will keep surfacing
- **Start with writing**: Always begin projects in text form
- **Review regularly**: Set aside time weekly to prune and update
- **PARA Method**: Projects, Areas, Resources, Archive ([Tiago Forte](https://fortelabs.com/blog/para/))
- **PARA Method**: Projects, Areas, Resources, Archive
([Tiago Forte](https://fortelabs.com/blog/para/))
## Setup Summary
✅ Dependencies installed (pnpm/npm)
✅ Folder structure created
Git repository initialized and disconnected from original
✅ CLAUDE.md personalized
✅ First-run setup completed
[✅ MCP Gemini Vision configured - if set up]
[✅ First commit made - if git was initialized]
✅ Dependencies installed (pnpm/npm) ✅ Folder structure created ✅ Git
repository initialized and disconnected from original ✅ CLAUDE.md personalized
First-run setup completed [✅ MCP Gemini Vision configured - if set up] [✅
First commit made - if git was initialized]
```
## Important Implementation Notes
@@ -291,24 +328,30 @@ Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
### Handling Multiple Vaults
When multiple vaults are detected:
1. **Always list all vaults found** with clear numbering and details
2. **Require explicit selection** - don't assume which vault to use
3. **Confirm the selection** before proceeding with import
4. **Handle ambiguous responses** - if user provides unclear input (like pasting a screenshot), ask for clarification:
- "I see you've shared a screenshot. Could you please type the number (1-3) of the vault you'd like to import?"
- "I need a clear selection. Please type '1', '2', or '3' to choose a vault, or 'skip' to start fresh."
4. **Handle ambiguous responses** - if user provides unclear input (like pasting
a screenshot), ask for clarification:
- "I see you've shared a screenshot. Could you please type the number (1-3)
of the vault you'd like to import?"
- "I need a clear selection. Please type '1', '2', or '3' to choose a vault,
or 'skip' to start fresh."
### Never Proceed Without Clear Confirmation
If the user's response is unclear:
- Don't guess or assume
- Ask for explicit confirmation
- Provide clear options again
- Example: "I want to make sure I import the right vault. Please type the number of your choice (1, 2, or 3)."
- Example: "I want to make sure I import the right vault. Please type the number
of your choice (1, 2, or 3)."
## Interactive Example
```
````
User: claude run init-bootstrap
Assistant: Welcome! I'll help you set up your personalized Obsidian + Claude configuration.
@@ -330,34 +373,48 @@ Now setting up your environment...
[Installs dependencies with pnpm/npm]
*Why: These tools enable Claude Code to work with your vault effectively*
🔓 **Disconnecting from Original Repository**
[Removes git remote to disconnect from original]
*Why: This ensures you won't accidentally push your personal notes to the public repo*
🔓 **Repository Setup**
📂 **Creating Folder Structure**
[Creates folders based on your chosen organization method]
*Why: A good structure helps you organize and find your knowledge effectively*
**Will you be contributing to claudesidian development?**
- **No** (Personal vault only) → I'll remove GitHub workflows and disconnect from the repo
- **Yes** (I want to contribute) → I'll keep the development setup intact
🎯 **Finalizing Setup**
[Checks git status and removes first-run marker]
*Why: Git gives you version control, and removing the marker ensures you won't see the welcome message again*
[Implementation:]
```bash
# If user says "No" (personal vault):
rm -rf .github # Remove GitHub workflows
git remote remove origin # Disconnect from claudesidian repo
✅ Folder renamed (if requested)
✅ Dependencies installed
✅ Core folders created
✅ Git repository ready (disconnected from original claudesidian)
✅ First-run marker removed
# If user says "Yes" (contributing):
# Keep .github folder and origin remote
echo "Development setup preserved for contributing"
````
_Why: Personal vaults don't need GitHub Actions, but contributors benefit from
the automation_
📂 **Creating Folder Structure** [Creates folders based on your chosen
organization method] _Why: A good structure helps you organize and find your
knowledge effectively_
🎯 **Finalizing Setup** [Checks git status and removes first-run marker] _Why:
Git gives you version control, and removing the marker ensures you won't see the
welcome message again_
✅ Folder renamed (if requested) ✅ Dependencies installed ✅ Core folders
created ✅ Git repository ready (disconnected from original claudesidian) ✅
First-run marker removed
Now let me ask you a few questions to customize your setup:
🔍 **Searching for existing Obsidian vaults...**
[Searches ~/Documents, ~/Desktop, ~/, and parent directories]
🔍 **Searching for existing Obsidian vaults...** [Searches ~/Documents,
~/Desktop, ~/, and parent directories]
### Case 1: Single Vault Found
Found Obsidian vault at: ~/Documents/MyNotes
📊 Vault stats: 2,517 markdown files, 1.1GB total size
Would you like to import this vault?
Found Obsidian vault at: ~/Documents/MyNotes 📊 Vault stats: 2,517 markdown
files, 1.1GB total size Would you like to import this vault?
- **yes** - Import this vault
- **no** - Search for a different vault
- **skip** - Start fresh without importing
@@ -382,6 +439,7 @@ User: yes
- Contains: Personal notes, drafts
**Which vault would you like to import?**
- Enter **1-3** to select a vault
- **all** - Import all vaults (each to a separate folder)
- **skip** - Start fresh without importing
@@ -389,45 +447,47 @@ User: yes
User: 1
**Confirming your selection:**
You selected: ~/Documents/MyNotes (2,517 files, 1.1GB)
**Confirming your selection:** You selected: ~/Documents/MyNotes (2,517 files,
1.1GB)
Is this correct? (yes/no)
User: yes
Great! I'll import your vault to OLD_VAULT/ where it will be safely preserved. You can migrate files to the PARA folders at your own pace.
Great! I'll import your vault to OLD_VAULT/ where it will be safely preserved.
You can migrate files to the PARA folders at your own pace.
📦 **Analyzing your vault structure...**
[Running tree to see folder hierarchy]
[Sampling notes to understand content]
[Detecting naming patterns from recent files]
📦 **Analyzing your vault structure...** [Running tree to see folder hierarchy]
[Sampling notes to understand content] [Detecting naming patterns from recent
files]
I can see you're using:
- A modified PARA structure with custom folders
- Date-prefixed files for daily notes (YYYY-MM-DD)
- Project folders with nested research
- Heavy use of the Resources folder for reference material
📦 **Importing your vault...**
[Copying files to OLD_VAULT/]
[Preserving .obsidian settings]
[Checking for plugin folders]
📦 **Importing your vault...** [Copying files to OLD_VAULT/] [Preserving
.obsidian settings] [Checking for plugin folders]
✅ Imported 2,517 files (1.1GB) to OLD_VAULT/
Your original structure is completely preserved!
✅ Imported 2,517 files (1.1GB) to OLD_VAULT/ Your original structure is
completely preserved!
Now let's personalize your setup:
1. **What's your name?**
*Why I'm asking:* I'll use this to personalize your CLAUDE.md file and help me understand your context better. This creates a more tailored experience where I can reference your work and interests naturally.
_Why I'm asking:_ I'll use this to personalize your CLAUDE.md file and help
me understand your context better. This creates a more tailored experience
where I can reference your work and interests naturally.
User: Noah Brier
2. **Would you like me to research your public work?**
*Why this helps:* By understanding your background, expertise, and interests, I can:
_Why this helps:_ By understanding your background, expertise, and interests,
I can:
- Tailor suggestions to your specific field and workflow
- Reference relevant examples from your domain
- Better understand the context of your questions
@@ -435,7 +495,9 @@ User: Noah Brier
User: Yes
Great! To make sure I find information about the real you, could you provide any of these details?
Great! To make sure I find information about the real you, could you provide any
of these details?
- Your company or organization
- Your location (city/country)
- A unique project you've worked on
@@ -450,9 +512,11 @@ Perfect! Let me search for you with those details...
[Searches for information using the provided identifying information]
Based on your details, I found you - Noah Brier, co-founder of Variance and Percolate, writer at every.to.
Based on your details, I found you - Noah Brier, co-founder of Variance and
Percolate, writer at every.to.
Let me confirm this is correct:
- Co-founded Variance (developer tools) and Percolate (marketing software)
- Write at every.to and Why Is This Interesting? newsletter
- Focus on systems thinking, creativity, and technology
@@ -463,8 +527,9 @@ User: yes
Excellent! I've identified the right profile.
**Building Your Profile**
Would you like me to read any specific pages to better understand your work?
**Building Your Profile** Would you like me to read any specific pages to better
understand your work?
- Your personal website or blog
- Recent articles or papers you've written
- Company/project pages
@@ -477,6 +542,7 @@ User: https://whyisthisinteresting.com/about, https://every.to/@noahbrier
[Fetches and analyzes the provided URLs]
I've built a comprehensive profile:
- You co-founded Variance (developer tools) and Percolate (marketing software)
- You write Why Is This Interesting? newsletter with Colin Nagy
- You explore creativity, technology, and systems thinking
@@ -486,70 +552,77 @@ Is there anything else I should know about your work or interests?
User: I'm really interested in how AI can augment thinking, not just writing
Got it! I'll remember that you focus on AI as a thinking tool, not just a writing assistant.
Got it! I'll remember that you focus on AI as a thinking tool, not just a
writing assistant.
3. **What will you primarily use this vault for?**
(research, writing, project management, daily notes, knowledge base, or combination?)
3. **What will you primarily use this vault for?** (research, writing, project
management, daily notes, knowledge base, or combination?)
User: I'll use it for research and writing, plus managing client projects
Assistant: Great! I'll configure your vault for research, writing, and client project management.
Assistant: Great! I'll configure your vault for research, writing, and client
project management.
2. **What specific projects are you currently working on?**
(I'll create folders for each in 01_Projects)
2. **What specific projects are you currently working on?** (I'll create folders
for each in 01_Projects)
User: I'm writing a book about productivity systems, building a SaaS app, and planning a conference talk
User: I'm writing a book about productivity systems, building a SaaS app, and
planning a conference talk
Assistant: Perfect! I'll set up project folders for:
- 01_Projects/Book - Productivity Systems/
- 01_Projects/SaaS App Development/
- 01_Projects/Conference Talk/
3. **What ongoing areas of responsibility do you maintain?**
(These go in 02_Areas - things without an end date)
- 01_Projects/Book - Productivity Systems/
- 01_Projects/SaaS App Development/
- 01_Projects/Conference Talk/
3. **What ongoing areas of responsibility do you maintain?** (These go in
02_Areas - things without an end date)
User: My newsletter, health & fitness, personal finances, and family activities
Assistant: I'll create area folders for:
- 02_Areas/Newsletter/
- 02_Areas/Health & Fitness/
- 02_Areas/Finances/
- 02_Areas/Family/
4. **What topics do you frequently research or reference?**
(I'll organize these in 03_Resources)
- 02_Areas/Newsletter/
- 02_Areas/Health & Fitness/
- 02_Areas/Finances/
- 02_Areas/Family/
4. **What topics do you frequently research or reference?** (I'll organize these
in 03_Resources)
User: AI tools, productivity methods, SaaS metrics, and writing techniques
Assistant: Setting up resource folders for:
- 03_Resources/AI Tools/
- 03_Resources/Productivity Methods/
- 03_Resources/SaaS Metrics/
- 03_Resources/Writing Techniques/
- 03_Resources/AI Tools/
- 03_Resources/Productivity Methods/
- 03_Resources/SaaS Metrics/
- 03_Resources/Writing Techniques/
[Continues with questions...]
**Gemini Vision Setup**
Gemini Vision is already included in claudesidian! It can analyze images, PDFs, and videos in your vault.
To activate it, you just need a free Google API key (takes 30 seconds).
Would you like to set it up now? (yes/no/later)
**Gemini Vision Setup** Gemini Vision is already included in claudesidian! It
can analyze images, PDFs, and videos in your vault. To activate it, you just
need a free Google API key (takes 30 seconds). Would you like to set it up now?
(yes/no/later)
User: later
No problem! You can set it up anytime by running `/setup-gemini` when you're ready.
No problem! You can set it up anytime by running `/setup-gemini` when you're
ready.
**Firecrawl Setup**
Firecrawl is a game-changer for research! Save any article or website directly to your vault as markdown.
Perfect for building a permanent, searchable research library.
Would you like to set it up? (yes/no/later)
**Firecrawl Setup** Firecrawl is a game-changer for research! Save any article
or website directly to your vault as markdown. Perfect for building a permanent,
searchable research library. Would you like to set it up? (yes/no/later)
User: yes
Great choice! Firecrawl will transform how you collect research.
Assistant: Excellent! Here's how to get your API key:
1. Go to https://aistudio.google.com/apikey
2. Click "Create API Key"
3. Copy the key (starts with AIzaSy...)
Once you have it, paste it here and I'll configure everything for you.
Once you have it, paste it here and I'll configure everything for you.
+22 -6
View File
@@ -1,13 +1,19 @@
---
name: release
description: Automatically bump version, update changelog, commit, tag, and push a new release based on recent changes
description:
Automatically bump version, update changelog, commit, tag, and push a new
release based on recent changes
allowed-tools: [Read, Write, Edit, MultiEdit, Bash, Grep]
argument-hint: "(optional) 'major', 'minor', 'patch', or leave blank for auto-detection"
argument-hint:
"(optional) 'major', 'minor', 'patch', or leave blank for auto-detection"
---
# Release Command
Automates the entire release process: analyzes recent commits to determine version bump type, updates version in package.json, moves unreleased changelog entries to the new version, commits everything, creates a git tag, and pushes to GitHub.
Automates the entire release process: analyzes recent commits to determine
version bump type, updates version in package.json, moves unreleased changelog
entries to the new version, commits everything, creates a git tag, and pushes to
GitHub.
## Task
@@ -62,11 +68,14 @@ Automates the entire release process: analyzes recent commits to determine versi
### Semantic Versioning (MAJOR.MINOR.PATCH)
**Quick Decision Guide:**
- Can users do something they couldn't do before? → **MINOR**
- Did something that worked break? → **MAJOR** (if breaking) or **PATCH** (if fixing)
- Did something that worked break? → **MAJOR** (if breaking) or **PATCH** (if
fixing)
- Did something that worked get better? → **PATCH**
**MAJOR** (1.0.0 → 2.0.0):
- Breaking changes that require users to change their code/config
- Removing features or commands
- Changing command syntax or behavior incompatibly
@@ -74,6 +83,7 @@ Automates the entire release process: analyzes recent commits to determine versi
- Commits with "!" after type (e.g., "feat!:")
**MINOR** (1.0.0 → 1.1.0):
- **NEW capabilities** added (not enhancements to existing features)
- Making something possible that wasn't possible before
- New commands, new tools, new integrations
@@ -88,12 +98,14 @@ Automates the entire release process: analyzes recent commits to determine versi
- Enabling a feature to work offline when it required internet before
**PATCH** (1.0.0 → 1.0.1):
- Bug fixes and minor improvements
- Enhancements to existing features (that already worked)
- Performance improvements
- Documentation updates
- Refactoring without changing behavior
- Commits with "fix:", "docs:", "style:", "refactor:", "perf:", "test:", "chore:"
- Commits with "fix:", "docs:", "style:", "refactor:", "perf:", "test:",
"chore:"
- Examples:
- Making an existing command smarter (but not enabling new use cases)
- Improving error messages
@@ -104,18 +116,22 @@ Automates the entire release process: analyzes recent commits to determine versi
### Commit Message Best Practices
**Use "feat:" only for NEW features:**
-`feat: add vault import capability`
-`feat: enhance vault import` (should be `fix:` or `refactor:`)
**Use "fix:" for improvements and corrections:**
-`fix: improve vault detection accuracy`
-`fix: correct file counting in init-bootstrap`
**Use "refactor:" for code improvements:**
-`refactor: enhance profile building with URL fetching`
-`refactor: make init-bootstrap questions smarter`
**Use "perf:" for performance improvements:**
-`perf: optimize vault analysis for large vaults`
## Example Usage
@@ -165,4 +181,4 @@ claude run release major
- Dry run mode: Show what would happen without making changes
- Confirmation prompt before pushing
- Validation of version format
- Check for existing tags before creating
- Check for existing tags before creating
+9 -3
View File
@@ -1,6 +1,7 @@
# Research Assistant
Conduct thorough research on topics by searching the vault and synthesizing findings.
Conduct thorough research on topics by searching the vault and synthesizing
findings.
## Process
@@ -27,31 +28,36 @@ Conduct thorough research on topics by searching the vault and synthesizing find
# Research Summary: [Topic]
## Existing Knowledge
- What's already in the vault
- Key insights from previous work
## Key Themes
1. Theme 1
- Supporting notes: [[note1]], [[note2]]
- Key insight: ...
2. Theme 2
- Supporting notes: [[note3]], [[note4]]
- Key insight: ...
## Contradictions/Tensions
- Where ideas conflict
- Unresolved questions
## Gaps
- What's missing
- What to research next
## Connections
- Related topics: [[topic1]], [[topic2]]
- Surprising links: ...
## Recommended Next Steps
1. Specific research needed
2. Questions to explore
3. Experiments to try
@@ -62,4 +68,4 @@ Conduct thorough research on topics by searching the vault and synthesizing find
- Cast a wide net initially, then focus
- Look for surprising connections
- Don't ignore contradictions - they're often where insights live
- Always suggest concrete next actions
- Always suggest concrete next actions
+13 -6
View File
@@ -1,13 +1,19 @@
# Thinking Partner
You are a collaborative thinking partner specializing in helping people explore complex problems. Your role is to facilitate thinking through careful questioning and exploration, not to rush toward solutions.
You are a collaborative thinking partner specializing in helping people explore
complex problems. Your role is to facilitate thinking through careful
questioning and exploration, not to rush toward solutions.
## Core Behaviors
1. **Ask before answering** - Lead with questions that help clarify and deepen understanding
2. **Track insights** - Maintain a running log of key discoveries and connections
3. **Resist solutioning** - Stay in exploration mode until explicitly asked to move forward
4. **Connect ideas** - Help identify patterns and relationships across different notes
1. **Ask before answering** - Lead with questions that help clarify and deepen
understanding
2. **Track insights** - Maintain a running log of key discoveries and
connections
3. **Resist solutioning** - Stay in exploration mode until explicitly asked to
move forward
4. **Connect ideas** - Help identify patterns and relationships across different
notes
5. **Surface assumptions** - Gently challenge implicit beliefs and assumptions
## Workflow
@@ -34,4 +40,5 @@ When engaged as a thinking partner:
## Remember
The goal is not to have answers but to help discover them. Your value is in the quality of exploration, not the speed of resolution.
The goal is not to have answers but to help discover them. Your value is in the
quality of exploration, not the speed of resolution.
+155 -108
View File
@@ -1,13 +1,19 @@
---
name: upgrade
description: Intelligently upgrade claudesidian with new features while preserving user customizations using AI-powered semantic analysis
description:
Intelligently upgrade claudesidian with new features while preserving user
customizations using AI-powered semantic analysis
allowed-tools: [Read, Write, Edit, MultiEdit, Bash, WebFetch, Grep, Glob]
argument-hint: "(optional) 'check' to preview changes, 'force' to skip confirmations"
argument-hint:
"(optional) 'check' to preview changes, 'force' to skip confirmations"
---
# Smart Upgrade Command
Intelligently upgrades your claudesidian installation by fetching the latest release from GitHub and using AI-powered semantic analysis to merge new features with your existing customizations. Preserves user intent while adding new capabilities.
Intelligently upgrades your claudesidian installation by fetching the latest
release from GitHub and using AI-powered semantic analysis to merge new features
with your existing customizations. Preserves user intent while adding new
capabilities.
## Task
@@ -21,155 +27,173 @@ Intelligently upgrades your claudesidian installation by fetching the latest rel
## Process
### 1. **Version Check & Setup**
- Get current version from package.json
- Create timestamped backup in `.backup/upgrade-YYYY-MM-DD-HHMMSS/`
- Clone latest claudesidian to temp directory (doesn't affect user's repo):
```bash
# Get fresh copy in .tmp dir (hidden from Obsidian) - user's repo stays disconnected
git clone --depth=1 --branch=main https://github.com/heyitsnoah/claudesidian.git .tmp/claudesidian-upgrade
```
- Now we have latest version to compare against
- Get current version from package.json
- Create timestamped backup in `.backup/upgrade-YYYY-MM-DD-HHMMSS/`
- Clone latest claudesidian to temp directory (doesn't affect user's repo):
```bash
# Get fresh copy in .tmp dir (hidden from Obsidian) - user's repo stays disconnected
git clone --depth=1 --branch=main https://github.com/heyitsnoah/claudesidian.git .tmp/claudesidian-upgrade
```
- Now we have latest version to compare against
### 2. **Create Upgrade Checklist**
- Compare system files between current directory and .tmp/claudesidian-upgrade/:
```bash
# Find all system files that differ
diff -qr . .tmp/claudesidian-upgrade/ --include="*.md" --include="*.sh" --include="*.json" |
grep -E '(\.claude/|\.scripts/|package\.json|CHANGELOG\.md|README\.md)' |
grep -v '(00_|01_|02_|03_|04_|05_|06_|\.obsidian|CLAUDE\.md)'
```
- Create checklist of files that need review
- Explicitly EXCLUDE:
- User content folders (00_Inbox, 01_Projects, etc.)
- User's CLAUDE.md (their personalized version)
- vault-config.json (user's vault configuration)
- .obsidian/ (user's Obsidian settings)
- Any .md files in the root except README and CHANGELOG
- Create `.upgrade-checklist.md` with only system files that differ
- Mark each file with status: `[ ] pending`, `[x] updated`, `[-] skipped`
- Group files by type for easier review:
```markdown
## Commands (12 files)
[ ] .claude/commands/init-bootstrap.md
[ ] .claude/commands/release.md
[ ] .claude/commands/thinking-partner.md
...
## Settings (2 files)
[ ] .claude/settings.json
[ ] .claude/settings.local.json
- Compare system files between current directory and .tmp/claudesidian-upgrade/:
```bash
# Find all system files that differ
diff -qr . .tmp/claudesidian-upgrade/ --include="*.md" --include="*.sh" --include="*.json" |
grep -E '(\.claude/|\.scripts/|package\.json|CHANGELOG\.md|README\.md)' |
grep -v '(00_|01_|02_|03_|04_|05_|06_|\.obsidian|CLAUDE\.md)'
```
- Create checklist of files that need review
- Explicitly EXCLUDE:
- User content folders (00_Inbox, 01_Projects, etc.)
- User's CLAUDE.md (their personalized version)
- vault-config.json (user's vault configuration)
- .obsidian/ (user's Obsidian settings)
- Any .md files in the root except README and CHANGELOG
- Create `.upgrade-checklist.md` with only system files that differ
- Mark each file with status: `[ ] pending`, `[x] updated`, `[-] skipped`
- Group files by type for easier review:
## Core Files (3 files)
[ ] package.json
[ ] CHANGELOG.md
[ ] README.md
```
```markdown
## Commands (12 files)
[ ] .claude/commands/init-bootstrap.md [ ] .claude/commands/release.md [ ]
.claude/commands/thinking-partner.md ...
## Settings (2 files)
[ ] .claude/settings.json [ ] .claude/settings.local.json
## Core Files (3 files)
[ ] package.json [ ] CHANGELOG.md [ ] README.md
```
### 3. **File-by-File Review**
**⚠️ CRITICAL IMPLEMENTATION REQUIREMENT:**
- **NEVER blindly overwrite files with `cat > file` or `cp`**
- **ALWAYS show diffs to the user first**
- **ALWAYS ask for confirmation before replacing files**
- **Skipping these steps can lose user customizations!**
**⚠️ CRITICAL IMPLEMENTATION REQUIREMENT:**
- **NEVER blindly overwrite files with `cat > file` or `cp`**
- **ALWAYS show diffs to the user first**
- **ALWAYS ask for confirmation before replacing files**
- **Skipping these steps can lose user customizations!**
For EACH file in the checklist:
1. Read current checklist status from `.upgrade-checklist.md`
2. **MANDATORY: Show the diff between local and upstream**:
```bash
# ALWAYS show this to the user!
diff -u current/file .tmp/claudesidian-upgrade/file
```
3. Determine update strategy:
- **No local changes**: Direct replace from upstream
- **Never update**: User's CLAUDE.md, vault-config.json, .mcp.json
- **Local changes detected**: Ask user:
For EACH file in the checklist:
1. Read current checklist status from `.upgrade-checklist.md`
2. **MANDATORY: Show the diff between local and upstream**:
```bash
# ALWAYS show this to the user!
diff -u current/file .tmp/claudesidian-upgrade/file
```
3. Determine update strategy:
- **No local changes**: Direct replace from upstream
- **Never update**: User's CLAUDE.md, vault-config.json, .mcp.json
- **Local changes detected**: Ask user:
```
File: .claude/commands/thinking-partner.md has local modifications
File: .claude/commands/thinking-partner.md has local modifications
Options:
1. Keep your version (skip update)
2. Take upstream version (lose your changes)
3. View diff and decide
4. Try to merge both (AI-assisted)
Options:
1. Keep your version (skip update)
2. Take upstream version (lose your changes)
3. View diff and decide
4. Try to merge both (AI-assisted)
Choice (1/2/3/4): _
```
4. Apply the chosen strategy
5. **CRITICAL: Update the checklist file immediately**:
```markdown
[ ] .claude/commands/init-bootstrap.md → becomes → [x] .claude/commands/init-bootstrap.md
Choice (1/2/3/4): _
```
6. Save `.upgrade-checklist.md` after EVERY file update
7. Move to next file
4. Apply the chosen strategy
5. **CRITICAL: Update the checklist file immediately**:
```markdown
[ ] .claude/commands/init-bootstrap.md → becomes → [x]
.claude/commands/init-bootstrap.md
```
6. Save `.upgrade-checklist.md` after EVERY file update
7. Move to next file
### 4. **Update Types**
- **Safe to replace**: `.claude/commands/*.md`, `.claude/agents/*.md`, `.scripts/*`
- **Needs review**: `package.json` (preserve user's custom scripts)
- **Never touch**: User content folders, CLAUDE.md, API configs
- **Safe to replace**: `.claude/commands/*.md`, `.claude/agents/*.md`,
`.scripts/*`
- **Needs review**: `package.json` (preserve user's custom scripts)
- **Never touch**: User content folders, CLAUDE.md, API configs
### 5. **Progress Tracking**
- Use TodoWrite tool to track progress alongside the checklist
- Save progress after each file in `.upgrade-checklist.md`
- **MUST mark items in checklist**:
- `[x]` = completed
- `[-]` = skipped (user customization)
- `[ ]` = still pending
- If interrupted, can resume from where you left off
- Show progress: "Updating file 5 of 23..."
- Clear indication of what's been done and what's remaining
- Use TodoWrite tool to track progress alongside the checklist
- Save progress after each file in `.upgrade-checklist.md`
- **MUST mark items in checklist**:
- `[x]` = completed
- `[-]` = skipped (user customization)
- `[ ]` = still pending
- If interrupted, can resume from where you left off
- Show progress: "Updating file 5 of 23..."
- Clear indication of what's been done and what's remaining
### 6. **Verification Check**
- Re-check all system files against the checklist
- Compare with checklist to identify:
- Files marked `[ ]` pending = likely missed (problem)
- Files marked `[-]` skipped = intentionally kept different (fine)
- Files marked `[x]` updated but still in diff = merge issues or user edits (review)
- Show verification results:
```
✅ All required files updated successfully
️ 2 files intentionally kept with user customizations:
- .claude/commands/thinking-partner.md (user's concise style)
- package.json (user's custom scripts preserved)
- or -
⚠️ Warning: 2 files appear to be missed (still marked pending):
- .claude/commands/release.md
- .scripts/vault-stats.sh
```
- Only flag as problem if files are still marked `[ ]` pending in checklist
- Re-check all system files against the checklist
- Compare with checklist to identify:
- Files marked `[ ]` pending = likely missed (problem)
- Files marked `[-]` skipped = intentionally kept different (fine)
- Files marked `[x]` updated but still in diff = merge issues or user edits
(review)
- Show verification results:
```
✅ All required files updated successfully
️ 2 files intentionally kept with user customizations:
- .claude/commands/thinking-partner.md (user's concise style)
- package.json (user's custom scripts preserved)
- or -
⚠️ Warning: 2 files appear to be missed (still marked pending):
- .claude/commands/release.md
- .scripts/vault-stats.sh
```
- Only flag as problem if files are still marked `[ ]` pending in checklist
### 7. **Final Steps**
- Update version in package.json
- Verify all commands work
- Clean up temp directory: `rm -rf .tmp/claudesidian-upgrade`
- Save final checklist for reference (shows what was updated vs skipped)
- Show summary of what was updated
- Update version in package.json
- Verify all commands work
- Clean up temp directory: `rm -rf .tmp/claudesidian-upgrade`
- Save final checklist for reference (shows what was updated vs skipped)
- Show summary of what was updated
## Update Categories
### 🤖 AI-Powered Intelligent Merge
**Commands** (`.claude/commands/*.md`):
- Analyze user's prompt style, output preferences, workflow modifications
- Merge new features with existing customizations
- Preserve user's tone, structure, and specific requirements
**Agents** (`.claude/agents/*.md`):
- Understand user's interaction preferences
- Combine new capabilities with existing personality
- Maintain user's established workflows
**Templates** (`06_Metadata/Templates/*.md`):
- Preserve custom fields and structure
- Add new template features
- Maintain user's formatting preferences
### ⚡ Automatic Safe Updates
- **New commands/agents**: Purely additive, no conflicts
- **Scripts** (`.scripts/*`): Utility functions, safe to replace
- **Dependencies** (`package.json`): Security and feature updates
- **Documentation**: README, CONTRIBUTING updates
### 🛡️ Never Modified
- **User content**: All `00_*` through `06_*` folders (except templates)
- **Personal config**: User's `CLAUDE.md`
- **API keys**: `.mcp.json`, environment variables
@@ -182,6 +206,7 @@ When Claude detects conflicts:
### Example Scenarios:
**Scenario 1: Command Enhancement**
```
📝 thinking-partner command has updates:
@@ -202,6 +227,7 @@ Options:
```
**Scenario 2: Template Updates**
```
📋 Project Template has changes:
@@ -220,27 +246,33 @@ Apply merge? (y/n/preview)
## Command Usage
### Preview Mode (Recommended First Run)
```
/upgrade check
```
- Shows what would be updated
- Displays intelligent merge previews
- No changes made to files
- Safe to run anytime
### Interactive Upgrade
```
/upgrade
```
- Step-by-step confirmation for each change
- Shows before/after for modified files
- Allows selective application of updates
- Creates automatic backups
### Batch Upgrade (Advanced)
```
/upgrade force
```
- Applies all safe updates automatically
- Still prompts for complex merges
- Faster for users comfortable with the process
@@ -249,11 +281,13 @@ Apply merge? (y/n/preview)
## Safety Features
### Automatic Backups
- Complete backup before any changes: `.backup/upgrade-[timestamp]/`
- Individual file backups for each modification
- Backup includes current git state and uncommitted changes
### Rollback Support
```
# If upgrade causes issues:
/rollback-upgrade [timestamp]
@@ -261,12 +295,14 @@ Apply merge? (y/n/preview)
```
### Verification Steps
- Post-upgrade functionality testing
- Command validation (runs test commands)
- MCP server connectivity check
- Git repository integrity verification
### Incremental Application
- Updates applied one file at a time
- Validation after each critical change
- Stops on first error with clear diagnostics
@@ -275,23 +311,28 @@ Apply merge? (y/n/preview)
## Common Pitfalls to Avoid
### ⚠️ Selective Updates Problem
**Never cherry-pick files based only on release notes!** This leads to:
- Missing critical command updates
- Incomplete feature implementations
- Broken dependencies between files
- Users not getting all improvements
**Always use `git diff HEAD upstream/main --name-only`** to get the complete list of changed files, then update ALL relevant files systematically.
**Always use `git diff HEAD upstream/main --name-only`** to get the complete
list of changed files, then update ALL relevant files systematically.
## Error Handling
### Common Scenarios
- **No internet connection**: Graceful failure with offline options
- **GitHub API rate limits**: Intelligent retry with backoff
- **Merge conflicts**: Clear explanation and manual resolution options
- **Permission issues**: Helpful guidance on fixing file permissions
### Recovery Options
- **Partial failure**: Continue from last successful step
- **Complete failure**: Full rollback to pre-upgrade state
- **Git conflicts**: Merge upstream changes with local commits
@@ -300,19 +341,23 @@ Apply merge? (y/n/preview)
## Advanced Features
### Custom Merge Rules
Users can create `.upgrade-rules.json` to specify:
- Files to always skip
- Custom merge preferences
- Automatic approval for specific change types
- Backup retention policies
### Integration with Git
- Commits each major change separately
- Meaningful commit messages describing updates
- Preserves user's branch structure
- Handles git conflicts intelligently
### Selective Updates
```
/upgrade commands-only # Update just commands
/upgrade agents-only # Update just agents
@@ -510,4 +555,6 @@ Choice (1/2/3) > 1
- User customizations preserved where intended
```
This intelligent upgrade system leverages Claude's semantic understanding to provide the smoothest possible upgrade experience while ensuring no user customizations are lost.
This intelligent upgrade system leverages Claude's semantic understanding to
provide the smoothest possible upgrade experience while ensuring no user
customizations are lost.
+15 -3
View File
@@ -35,50 +35,62 @@ Create a weekly synthesis note:
# Weekly Synthesis - Week of [Date]
## Week at a Glance
- Notes created: [X]
- Projects active: [List]
- Major accomplishments: [List]
## Key Themes
### Theme 1: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
### Theme 2: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
## Major Insights
1. [Insight with context]
2. [Insight with context]
## Progress by Project
### [Project Name]
- What advanced:
- What advanced:
- What's blocked:
- Next week's focus:
## Questions Emerged
- [Question 1 - and why it matters]
- [Question 2 - and why it matters]
## Energy Audit
- What gave energy:
- What gave energy:
- What drained energy:
- What to adjust:
## Connections Made
- [Note A] ←→ [Note B]: [Why significant]
- [Concept X] ←→ [Concept Y]: [New understanding]
## Next Week's Intentions
1. [Primary focus]
2. [Secondary focus]
3. [Thing to explore]
## To Process
- Inbox items: [count]
- Orphaned notes: [list]
- Missing connections: [identified]
@@ -89,4 +101,4 @@ Create a weekly synthesis note:
- Archive completed projects
- Clean up inbox
- Update project status
- Plan next week's focus
- Plan next week's focus
@@ -5,6 +5,7 @@
## Prerequisites Check
Run these commands to verify you have everything needed:
```bash
node --version # Should be v22+
pnpm --version # Should be installed
@@ -12,19 +13,22 @@ claude --version # Claude Code should be installed
```
If any are missing:
- Node.js: Install from [nodejs.org](https://nodejs.org/) (v22+)
- pnpm: `npm install -g pnpm`
- Claude Code: Download from [claude.ai/code](https://claude.ai/code)
## Step 1: Get Your Gemini API Key
1. Go to [https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)
1. Go to
[https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)
2. Click "Create API Key"
3. Copy the key (starts with `AIzaSy...`)
## Step 2: Set Up Environment Variable
### For Linux/macOS with Bash:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.bashrc
source ~/.bashrc
@@ -32,6 +36,7 @@ echo $GEMINI_API_KEY # Verify it shows your key
```
### For Linux/macOS with Zsh:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.zshrc
source ~/.zshrc
@@ -39,6 +44,7 @@ echo $GEMINI_API_KEY # Verify it shows your key
```
### For Windows PowerShell:
```powershell
[System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key-here', 'User')
# Restart PowerShell
@@ -50,11 +56,13 @@ $env:GEMINI_API_KEY # Verify it shows your key
**⚠️ CRITICAL: This step MUST be done before adding the MCP server!**
Navigate to your Obsidian vault:
```bash
cd ~/dev/02_Areas/Obsidian # Or wherever your vault is
```
Install the required dependencies:
```bash
# Install npm packages (REQUIRED - do this first!)
pnpm install
@@ -65,9 +73,12 @@ pnpm install
# - Other dependencies from package.json
```
**Common Error Fix**: If you see `Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'`, you forgot to run `pnpm install`!
**Common Error Fix**: If you see
`Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'`,
you forgot to run `pnpm install`!
**To hide node_modules from Obsidian** (optional but recommended):
1. Open Obsidian
2. Go to Settings → Files & Links → Excluded files
3. Click "Manage"
@@ -79,18 +90,21 @@ This keeps your vault clean while using standard Node.js module resolution.
## Step 4: Register the MCP Server
**For project-scoped installation (recommended for team use):**
```bash
# Add server to project (creates .mcp.json file)
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
**For user-scoped installation (personal use across all projects):**
```bash
# Add server to your user config
claude mcp add --scope user gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
After adding, you'll need to edit the `.mcp.json` file to add your API key:
```json
{
"mcpServers": {
@@ -107,6 +121,7 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
```
**IMPORTANT**:
- The command must be run from the Obsidian vault root directory
- You MUST have run `pnpm install` first
- The `.mcp.json` file is gitignored for security
@@ -114,15 +129,16 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
## Step 5: Verify It's Working
1. **Open a NEW Claude Code window** (critical - must be new):
```bash
cd ~/dev/Obsidian
claude
```
2. **Check the server is connected**:
Type `/mcp` in Claude
2. **Check the server is connected**: Type `/mcp` in Claude
You should see:
```
gemini-vision ✔ connected
```
@@ -137,11 +153,13 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### "gemini-vision failed" or not showing in /mcp
1. **MOST COMMON ISSUE - Dependencies not installed**:
```bash
# If you see: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'
# Run this:
pnpm install
```
Then reconnect the MCP server in Claude Code.
2. **Check API key is configured**:
@@ -150,21 +168,24 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
- The key should be in the format: `"GEMINI_API_KEY": "AIzaSy..."`
3. **Test server can run directly**:
```bash
export GEMINI_API_KEY="your-api-key-here"
node .claude/mcp-servers/gemini-vision.mjs
```
Should show: "🚀 Gemini Vision MCP Server running"
Press Ctrl+C to exit.
Should show: "🚀 Gemini Vision MCP Server running" Press Ctrl+C to exit.
4. **Re-add the server (for project scope)**:
```bash
claude mcp remove gemini-vision --scope project
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
# Then edit .mcp.json to add your API key
```
4. **Check logs**:
5. **Check logs**:
```bash
# Find log directory
ls ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-gemini-vision/
@@ -178,12 +199,15 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### "Cannot find module" errors
1. **Verify package.json exists**:
```bash
cat package.json
```
Should show @google/generative-ai and @modelcontextprotocol/sdk
2. **Reinstall dependencies**:
```bash
rm -rf node_modules pnpm-lock.yaml
pnpm install
@@ -197,9 +221,11 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### Server runs but tools don't work
1. **Test API key directly**:
```bash
curl "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY"
```
Should return a list of models, not an error.
2. **Check file paths**:
@@ -211,6 +237,7 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
Once working, you can use these in Claude:
### Image Analysis
```
# Analyze an image
Use gemini-vision to analyze 05 Attachments/screenshot.png
@@ -229,6 +256,7 @@ Use gemini-vision to analyze multiple: image1.png, image2.png, image3.png
```
### Video Analysis (NEW!)
```
# Analyze a local video file
Use gemini-vision to analyze video 05 Attachments/video.mp4
@@ -240,14 +268,15 @@ Use gemini-vision to analyze YouTube video https://www.youtube.com/watch?v=VIDEO
Use gemini-vision to analyze video file.mp4 and extract all visible text
```
**Note:** Video processing may take 30-60 seconds as files need to reach ACTIVE state before analysis. The server will automatically wait and show progress updates.
**Note:** Video processing may take 30-60 seconds as files need to reach ACTIVE
state before analysis. The server will automatically wait and show progress
updates.
### Supported Formats
**Images:** JPG, JPEG, PNG, GIF, BMP, WebP
**Videos:** MP4, AVI, MOV, WebM, MKV, WMV, FLV, 3GP, M4V
**Documents:** PDF, TXT, DOC, DOCX, ODT, RTF
**Special:** YouTube URLs (direct support without download)
**Images:** JPG, JPEG, PNG, GIF, BMP, WebP **Videos:** MP4, AVI, MOV, WebM, MKV,
WMV, FLV, 3GP, M4V **Documents:** PDF, TXT, DOC, DOCX, ODT, RTF **Special:**
YouTube URLs (direct support without download)
## Quick Reinstall (If Already Set Up Once)
@@ -282,4 +311,4 @@ Then open a new Claude window and test.
---
*Last tested: September 2025*
_Last tested: September 2025_
+14 -4
View File
@@ -4,7 +4,8 @@ Model Context Protocol servers extend Claude Code's capabilities.
## Gemini Vision MCP
Adds powerful image and document analysis capabilities using Google's Gemini model.
Adds powerful image and document analysis capabilities using Google's Gemini
model.
### Features
@@ -21,15 +22,17 @@ Adds powerful image and document analysis capabilities using Google's Gemini mod
- Create a free API key
2. **Add to Environment**
```bash
# Add to ~/.zshrc or ~/.bashrc
export GEMINI_API_KEY='your-key-here'
# Reload shell
source ~/.zshrc
```
3. **Install Dependencies**
```bash
pnpm install
```
@@ -53,24 +56,28 @@ Once configured, these commands become available in Claude Code:
### Usage Examples
**Analyze Screenshot**
```
Analyze the image at 05_Attachments/screenshot.png
and tell me what it contains.
```
**Process Multiple Images**
```
Compare all images in 05_Attachments/Organized/
and identify common themes.
```
**Extract Text**
```
Extract all text from the PDF at
Extract all text from the PDF at
05_Attachments/document.pdf
```
**Rename Images**
```
Suggest better names for all images
in 05_Attachments/ based on their content.
@@ -79,14 +86,17 @@ in 05_Attachments/ based on their content.
### Troubleshooting
**"GEMINI_API_KEY not found"**
- Make sure you've added the key to your shell profile
- Restart your terminal and Claude Code
**"File not found"**
- Use absolute paths or paths relative to vault root
- Check file permissions
**Rate Limits**
- Free tier: 15 requests per minute
- Consider upgrading for heavy usage
@@ -101,4 +111,4 @@ in 05_Attachments/ based on their content.
- [MCP Documentation](https://modelcontextprotocol.io)
- [Gemini API Docs](https://ai.google.dev)
- [Claude Code MCP Guide](https://claude.ai/docs/mcp)
- [Claude Code MCP Guide](https://claude.ai/docs/mcp)
+340 -263
View File
@@ -1,208 +1,246 @@
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListToolsRequestSchema,
CallToolRequestSchema
} from "@modelcontextprotocol/sdk/types.js";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { GoogleAIFileManager } from "@google/generative-ai/server";
import fs from "fs/promises";
import path from "path";
import os from "os";
import { GoogleGenerativeAI } from '@google/generative-ai'
import { GoogleAIFileManager } from '@google/generative-ai/server'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js'
import fs from 'node:fs/promises'
import os from 'node:os'
import path from 'node:path'
const apiKey = process.env.GEMINI_API_KEY;
const apiKey = process.env.GEMINI_API_KEY
if (!apiKey) {
console.error("❌ GEMINI_API_KEY environment variable is required");
console.error("");
console.error("To fix this:");
console.error("");
console.error("1. Get your API key from: https://aistudio.google.com/apikey");
console.error("");
console.error("2. Add to your shell profile:");
console.error(" For macOS/Linux (add to ~/.zshrc or ~/.bashrc):");
console.error(" export GEMINI_API_KEY='your-actual-api-key-here'");
console.error("");
console.error(" For Windows PowerShell:");
console.error(" [System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key', 'User')");
console.error("");
console.error("3. Reload your terminal:");
console.error(" source ~/.zshrc (or source ~/.bashrc)");
console.error("");
console.error("4. Restart Claude Code");
console.error("");
console.error("For detailed instructions, see GEMINI_VISION_SETUP.md");
process.exit(1);
console.error('❌ GEMINI_API_KEY environment variable is required')
console.error('')
console.error('To fix this:')
console.error('')
console.error('1. Get your API key from: https://aistudio.google.com/apikey')
console.error('')
console.error('2. Add to your shell profile:')
console.error(' For macOS/Linux (add to ~/.zshrc or ~/.bashrc):')
console.error(" export GEMINI_API_KEY='your-actual-api-key-here'")
console.error('')
console.error(' For Windows PowerShell:')
console.error(
" [System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key', 'User')",
)
console.error('')
console.error('3. Reload your terminal:')
console.error(' source ~/.zshrc (or source ~/.bashrc)')
console.error('')
console.error('4. Restart Claude Code')
console.error('')
console.error('For detailed instructions, see GEMINI_VISION_SETUP.md')
process.exit(1)
}
const genAI = new GoogleGenerativeAI(apiKey);
const fileManager = new GoogleAIFileManager(apiKey);
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const genAI = new GoogleGenerativeAI(apiKey)
const fileManager = new GoogleAIFileManager(apiKey)
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' })
// Expand home directory in paths
function expandPath(filepath) {
if (filepath.startsWith("~/")) {
return path.join(os.homedir(), filepath.slice(2));
if (filepath.startsWith('~/')) {
return path.join(os.homedir(), filepath.slice(2))
}
return filepath;
return filepath
}
// Helper function to wait/sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
return new Promise((resolve) => setTimeout(resolve, ms))
}
// Upload file to Gemini
async function uploadFile(filePath) {
const expandedPath = expandPath(filePath);
const expandedPath = expandPath(filePath)
try {
await fs.access(expandedPath);
await fs.access(expandedPath)
} catch {
throw new Error(`File not found: ${filePath}`);
throw new Error(`File not found: ${filePath}`)
}
const ext = path.extname(expandedPath).toLowerCase();
const ext = path.extname(expandedPath).toLowerCase()
const mimeTypes = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.bmp': 'image/bmp',
'.webp': 'image/webp',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
'.doc': 'application/msword',
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.docx':
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.gif': 'image/gif',
'.jpeg': 'image/jpeg',
'.jpg': 'image/jpeg',
'.odt': 'application/vnd.oasis.opendocument.text',
'.pdf': 'application/pdf',
'.png': 'image/png',
'.rtf': 'application/rtf',
'.txt': 'text/plain',
'.webp': 'image/webp',
// Video formats
'.mp4': 'video/mp4',
'.avi': 'video/x-msvideo',
'.mov': 'video/quicktime',
'.webm': 'video/webm',
'.mkv': 'video/x-matroska',
'.wmv': 'video/x-ms-wmv',
'.flv': 'video/x-flv',
'.3gp': 'video/3gpp',
'.avi': 'video/x-msvideo',
'.flv': 'video/x-flv',
'.m4v': 'video/x-m4v',
};
'.mkv': 'video/x-matroska',
'.mov': 'video/quicktime',
'.mp4': 'video/mp4',
'.webm': 'video/webm',
'.wmv': 'video/x-ms-wmv',
}
const uploadResult = await fileManager.uploadFile(expandedPath, {
mimeType: mimeTypes[ext] || 'application/octet-stream',
});
})
let file = uploadResult.file;
let file = uploadResult.file
// For video files, poll until the file is in ACTIVE state
const videoExtensions = ['.mp4', '.avi', '.mov', '.webm', '.mkv', '.wmv', '.flv', '.3gp', '.m4v'];
const videoExtensions = [
'.mp4',
'.avi',
'.mov',
'.webm',
'.mkv',
'.wmv',
'.flv',
'.3gp',
'.m4v',
]
if (videoExtensions.includes(ext)) {
console.error(`Waiting for video file to process: ${path.basename(filePath)}`);
let attempts = 0;
const maxAttempts = 60; // Max 5 minutes (60 * 5 seconds)
console.error(
`Waiting for video file to process: ${path.basename(filePath)}`,
)
let attempts = 0
const maxAttempts = 60 // Max 5 minutes (60 * 5 seconds)
while (file.state !== 'ACTIVE' && attempts < maxAttempts) {
await sleep(5000); // Wait 5 seconds
attempts++;
await sleep(5000) // Wait 5 seconds
attempts++
// Get updated file status
const fileStatus = await fileManager.getFile(file.name);
file = fileStatus;
const fileStatus = await fileManager.getFile(file.name)
file = fileStatus
console.error(`Video processing status: ${file.state} (attempt ${attempts}/${maxAttempts})`);
console.error(
`Video processing status: ${file.state} (attempt ${attempts}/${maxAttempts})`,
)
if (file.state === 'FAILED') {
throw new Error(`Video processing failed for: ${filePath}`);
throw new Error(`Video processing failed for: ${filePath}`)
}
}
if (file.state !== 'ACTIVE') {
throw new Error(`Video processing timeout for: ${filePath}. File state: ${file.state}`);
throw new Error(
`Video processing timeout for: ${filePath}. File state: ${file.state}`,
)
}
console.error('Video file is ready for analysis');
console.error('Video file is ready for analysis')
}
return file;
return file
}
// Tool handlers
async function analyzeImage(args) {
const imagePath = args.image_path;
const prompt = args.prompt || "Describe this image in detail";
const file = await uploadFile(imagePath);
async function analyzeDocument(args) {
const documentPath = args.document_path
const prompt =
args.prompt || 'Analyze this document and provide a comprehensive summary'
const file = await uploadFile(documentPath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function analyzeImage(args) {
const imagePath = args.image_path
const prompt = args.prompt || 'Describe this image in detail'
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function analyzeMultiple(args) {
const imagePaths = args.image_paths;
const prompt = args.prompt || "Analyze these images";
const content = [prompt];
for (const imagePath of imagePaths) {
const file = await uploadFile(imagePath);
content.push({ fileData: { fileUri: file.uri, mimeType: file.mimeType }});
}
const result = await model.generateContent(content);
return result.response.text();
}
const imagePaths = args.image_paths
const prompt = args.prompt || 'Analyze these images'
async function extractText(args) {
const imagePath = args.image_path;
const format = args.format || "plain";
const prompts = {
plain: "Extract and transcribe all text from this image. Return only the text, nothing else.",
markdown: "Extract all text from this image and format it in markdown, preserving structure.",
structured: "Extract all text from this image and organize it with clear sections and structure."
};
const file = await uploadFile(imagePath);
const result = await model.generateContent([
prompts[format] || prompts.plain,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
const content = [prompt]
for (const imagePath of imagePaths) {
const file = await uploadFile(imagePath)
content.push({ fileData: { fileUri: file.uri, mimeType: file.mimeType } })
}
const result = await model.generateContent(content)
return result.response.text()
}
async function compareImages(args) {
const image1Path = args.image1_path;
const image2Path = args.image2_path;
const focus = args.focus || "differences";
const image1Path = args.image1_path
const image2Path = args.image2_path
const focus = args.focus || 'differences'
const prompts = {
differences: "Compare these two images and describe all the differences you can find.",
similarities: "Compare these two images and describe what they have in common.",
changes: "Describe what has changed between the first and second image."
};
changes: 'Describe what has changed between the first and second image.',
differences:
'Compare these two images and describe all the differences you can find.',
similarities:
'Compare these two images and describe what they have in common.',
}
const [file1, file2] = await Promise.all([
uploadFile(image1Path),
uploadFile(image2Path)
]);
uploadFile(image2Path),
])
const result = await model.generateContent([
prompts[focus] || prompts.differences,
{ fileData: { fileUri: file1.uri, mimeType: file1.mimeType }},
{ fileData: { fileUri: file2.uri, mimeType: file2.mimeType }}
]);
return result.response.text();
{ fileData: { fileUri: file1.uri, mimeType: file1.mimeType } },
{ fileData: { fileUri: file2.uri, mimeType: file2.mimeType } },
])
return result.response.text()
}
async function extractText(args) {
const imagePath = args.image_path
const format = args.format || 'plain'
const prompts = {
markdown:
'Extract all text from this image and format it in markdown, preserving structure.',
plain:
'Extract and transcribe all text from this image. Return only the text, nothing else.',
structured:
'Extract all text from this image and organize it with clear sections and structure.',
}
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompts[format] || prompts.plain,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function suggestFilename(args) {
const imagePath = args.image_path;
const maxLength = args.max_length || 60;
const includeDate = args.include_date || false;
const imagePath = args.image_path
const maxLength = args.max_length || 60
const includeDate = args.include_date || false
const prompt = `Analyze this image and suggest a descriptive filename for it.
Requirements:
- Maximum ${maxLength} characters (not including extension)
@@ -213,218 +251,257 @@ async function suggestFilename(args) {
- For screenshots: include the application or website name
- For diagrams: include the type and subject
- For photos: include the subject and context
- Return ONLY the filename suggestion, no explanation or extension`;
const file = await uploadFile(imagePath);
- Return ONLY the filename suggestion, no explanation or extension`
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
// Clean up the suggestion and format it
let suggestion = result.response.text().trim();
let suggestion = result.response.text().trim()
// Remove any file extension if accidentally included
suggestion = suggestion.replace(/\.(png|jpg|jpeg|gif|webp|pdf)$/i, '');
suggestion = suggestion.replace(/\.(png|jpg|jpeg|gif|webp|pdf)$/i, '')
// Replace spaces with hyphens
suggestion = suggestion.replace(/\s+/g, ' ').replace(/ /g, ' - ');
suggestion = suggestion.replace(/\s+/g, ' ').replace(/ /g, ' - ')
// Ensure it doesn't exceed max length
if (suggestion.length > maxLength) {
suggestion = suggestion.substring(0, maxLength).replace(/ - $/, '');
suggestion = suggestion.substring(0, maxLength).replace(/ - $/, '')
}
return suggestion;
}
async function analyzeDocument(args) {
const documentPath = args.document_path;
const prompt = args.prompt || "Analyze this document and provide a comprehensive summary";
const file = await uploadFile(documentPath);
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
return suggestion
}
// Analyze video files or YouTube URLs
async function analyzeVideo(args) {
const videoPath = args.video_path;
const youtubeUrl = args.youtube_url;
const prompt = args.prompt || "Summarize this video in detail, including key moments and any text or speech content";
const videoPath = args.video_path
const youtubeUrl = args.youtube_url
const prompt =
args.prompt ||
'Summarize this video in detail, including key moments and any text or speech content'
if (!videoPath && !youtubeUrl) {
throw new Error("Either video_path or youtube_url is required");
throw new Error('Either video_path or youtube_url is required')
}
if (videoPath && youtubeUrl) {
throw new Error("Please provide either video_path or youtube_url, not both");
throw new Error('Please provide either video_path or youtube_url, not both')
}
let fileData;
let fileData
if (youtubeUrl) {
// YouTube URLs can be passed directly to the API
fileData = { fileUri: youtubeUrl };
fileData = { fileUri: youtubeUrl }
} else {
// Upload local video file
const file = await uploadFile(videoPath);
fileData = { fileUri: file.uri, mimeType: file.mimeType };
const file = await uploadFile(videoPath)
fileData = { fileUri: file.uri, mimeType: file.mimeType }
}
const result = await model.generateContent([
prompt,
{ fileData }
]);
const result = await model.generateContent([prompt, { fileData }])
return result.response.text();
return result.response.text()
}
// Create MCP server
const server = new Server(
{ name: "gemini-vision", version: "1.0.0" },
{ capabilities: { tools: {} }}
);
{ name: 'gemini-vision', version: '1.0.0' },
{ capabilities: { tools: {} } },
)
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "analyze_image",
description: "Analyze an image - transcribe text, describe content, or answer questions",
description:
'Analyze an image - transcribe text, describe content, or answer questions',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
prompt: { type: "string", description: "What to do with the image", default: "Describe this image" }
image_path: { description: 'Path to the image file', type: 'string' },
prompt: {
default: 'Describe this image',
description: 'What to do with the image',
type: 'string',
},
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'analyze_image',
},
{
name: "analyze_multiple",
description: "Analyze multiple images at once",
description: 'Analyze multiple images at once',
inputSchema: {
type: "object",
properties: {
image_paths: { type: "array", items: { type: "string" }, description: "List of image paths" },
prompt: { type: "string", description: "What to do with the images", default: "Analyze these images" }
image_paths: {
description: 'List of image paths',
items: { type: 'string' },
type: 'array',
},
prompt: {
default: 'Analyze these images',
description: 'What to do with the images',
type: 'string',
},
},
required: ["image_paths"]
}
required: ['image_paths'],
type: 'object',
},
name: 'analyze_multiple',
},
{
name: "extract_text",
description: "Extract and transcribe all text from an image (OCR)",
description: 'Extract and transcribe all text from an image (OCR)',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
format: { type: "string", enum: ["plain", "markdown", "structured"], default: "plain" }
format: {
default: 'plain',
enum: ['plain', 'markdown', 'structured'],
type: 'string',
},
image_path: { description: 'Path to the image file', type: 'string' },
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'extract_text',
},
{
name: "compare_images",
description: "Compare two images and describe differences or similarities",
description:
'Compare two images and describe differences or similarities',
inputSchema: {
type: "object",
properties: {
image1_path: { type: "string", description: "Path to first image" },
image2_path: { type: "string", description: "Path to second image" },
focus: { type: "string", enum: ["differences", "similarities", "changes"], default: "differences" }
focus: {
default: 'differences',
enum: ['differences', 'similarities', 'changes'],
type: 'string',
},
image1_path: { description: 'Path to first image', type: 'string' },
image2_path: { description: 'Path to second image', type: 'string' },
},
required: ["image1_path", "image2_path"]
}
required: ['image1_path', 'image2_path'],
type: 'object',
},
name: 'compare_images',
},
{
name: "suggest_image_filename",
description: "Analyze an image and suggest a descriptive filename (without extension)",
description:
'Analyze an image and suggest a descriptive filename (without extension)',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
max_length: { type: "number", description: "Maximum filename length", default: 60 },
include_date: { type: "boolean", description: "Include date prefix in suggestion", default: false }
image_path: { description: 'Path to the image file', type: 'string' },
include_date: {
default: false,
description: 'Include date prefix in suggestion',
type: 'boolean',
},
max_length: {
default: 60,
description: 'Maximum filename length',
type: 'number',
},
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'suggest_image_filename',
},
{
name: "analyze_video",
description: "Analyze video files or YouTube URLs - extract content, summarize, transcribe speech, identify objects/text. Provide either video_path OR youtube_url",
description:
'Analyze video files or YouTube URLs - extract content, summarize, transcribe speech, identify objects/text. Provide either video_path OR youtube_url',
inputSchema: {
type: "object",
properties: {
video_path: { type: "string", description: "Path to local video file (MP4, AVI, MOV, etc.)" },
youtube_url: { type: "string", description: "YouTube video URL (e.g., https://www.youtube.com/watch?v=...)" },
prompt: { type: "string", description: "What to analyze in the video", default: "Summarize this video in detail" }
prompt: {
default: 'Summarize this video in detail',
description: 'What to analyze in the video',
type: 'string',
},
video_path: {
description: 'Path to local video file (MP4, AVI, MOV, etc.)',
type: 'string',
},
youtube_url: {
description:
'YouTube video URL (e.g., https://www.youtube.com/watch?v=...)',
type: 'string',
},
},
required: []
}
required: [],
type: 'object',
},
name: 'analyze_video',
},
{
name: "analyze_document",
description: "Analyze a PDF or document with custom prompts - extract specific information, find mentions of topics, summarize sections, etc.",
description:
'Analyze a PDF or document with custom prompts - extract specific information, find mentions of topics, summarize sections, etc.',
inputSchema: {
type: "object",
properties: {
document_path: { type: "string", description: "Path to the document file (PDF, DOC, DOCX, ODT, RTF, TXT)" },
prompt: { type: "string", description: "What to analyze or extract from the document", default: "Analyze this document and provide a comprehensive summary" }
document_path: {
description:
'Path to the document file (PDF, DOC, DOCX, ODT, RTF, TXT)',
type: 'string',
},
prompt: {
default:
'Analyze this document and provide a comprehensive summary',
description: 'What to analyze or extract from the document',
type: 'string',
},
},
required: ["document_path"]
}
}
]
}));
required: ['document_path'],
type: 'object',
},
name: 'analyze_document',
},
],
}))
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const { arguments: args, name } = request.params
try {
let result;
let result
switch (name) {
case "analyze_image":
result = await analyzeImage(args);
break;
case "analyze_multiple":
result = await analyzeMultiple(args);
break;
case "extract_text":
result = await extractText(args);
break;
case "compare_images":
result = await compareImages(args);
break;
case "suggest_image_filename":
result = await suggestFilename(args);
break;
case "analyze_document":
result = await analyzeDocument(args);
break;
case "analyze_video":
result = await analyzeVideo(args);
break;
case 'analyze_document':
result = await analyzeDocument(args)
break
case 'analyze_image':
result = await analyzeImage(args)
break
case 'analyze_multiple':
result = await analyzeMultiple(args)
break
case 'analyze_video':
result = await analyzeVideo(args)
break
case 'compare_images':
result = await compareImages(args)
break
case 'extract_text':
result = await extractText(args)
break
case 'suggest_image_filename':
result = await suggestFilename(args)
break
default:
throw new Error(`Unknown tool: ${name}`);
throw new Error(`Unknown tool: ${name}`)
}
return {
content: [{ type: "text", text: result }]
};
content: [{ text: result, type: 'text' }],
}
} catch (error) {
throw new Error(`Tool execution failed: ${error.message}`);
throw new Error(`Tool execution failed: ${error.message}`)
}
});
})
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("🚀 Gemini Vision MCP Server running");
const transport = new StdioServerTransport()
await server.connect(transport)
console.error('🚀 Gemini Vision MCP Server running')
}
main().catch(console.error);
main().catch(console.error)
+1 -1
View File
@@ -15,4 +15,4 @@
}
]
}
}
}