Merge branch 'main' into feature/add-download-and-pr-commands
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user