fix: resolve lonely if ESLint warning

This commit is contained in:
Noah Brier
2025-09-15 08:49:07 -04:00
parent 61d14875d5
commit 3909ab476c
29 changed files with 1300 additions and 790 deletions
+2 -7
View File
@@ -37,14 +37,9 @@
"ws": "weekly-synthesis"
},
"preferences": {
"primary_folders": [
"00_Inbox",
"01_Projects",
"02_Areas",
"03_Resources"
],
"primary_folders": ["00_Inbox", "01_Projects", "02_Areas", "03_Resources"],
"template_folder": "06_Metadata/Templates",
"archive_after_days": 30,
"default_note_location": "00_Inbox"
}
}
}
+20 -1
View File
@@ -5,38 +5,53 @@ Pre-configured commands to enhance your Claude Code + Obsidian workflow.
## Available Commands
### 🤔 thinking-partner
Engage Claude as a thinking partner for exploring complex problems.
```
/thinking-partner
```
Best for: Brainstorming, problem exploration, developing ideas
### 📥 inbox-processor
Process and organize items in your Inbox folder.
```
/inbox-processor
```
Best for: Weekly inbox cleanup, organizing captures
### 🔍 research-assistant
Conduct thorough research on any topic using your vault.
```
/research-assistant
```
Best for: Deep dives, literature reviews, knowledge synthesis
### 📅 daily-review
End-of-day review to capture progress and plan tomorrow.
```
/daily-review
```
Best for: Daily shutdown ritual, reflection
### 📊 weekly-synthesis
Create a comprehensive synthesis of the week's work.
```
/weekly-synthesis
```
Best for: Weekly reviews, pattern recognition
## Creating Custom Commands
@@ -52,16 +67,19 @@ Best for: Weekly reviews, pattern recognition
## Using Commands
### Method 1: Direct (in Claude Code)
```
/[command-name]
```
### Method 2: Reference in Chat
```
Use the thinking-partner command to help me explore [topic]
```
### Method 3: Manual
```
Follow the instructions in .claude/commands/[command].md
```
@@ -76,6 +94,7 @@ Follow the instructions in .claude/commands/[command].md
## Command Ideas
Consider creating commands for:
- Project retrospectives
- Meeting notes processing
- Book notes extraction
@@ -84,4 +103,4 @@ Consider creating commands for:
- Learning path creation
- Decision analysis
Remember: The best commands emerge from your actual workflows.
Remember: The best commands emerge from your actual workflows.
+33 -13
View File
@@ -1,18 +1,22 @@
---
description: Add or update YAML frontmatter properties to enhance note organization
description:
Add or update YAML frontmatter properties to enhance note organization
argument-hint: [file or folder path]
allowed-tools: Read, Write, Edit, Glob
---
You will analyze Obsidian notes and add intelligent YAML frontmatter properties to enhance organization and discoverability.
You will analyze Obsidian notes and add intelligent YAML frontmatter properties
to enhance organization and discoverability.
## Input
- Path: ${1} (file or folder to process)
- Current date: !`date +%Y-%m-%d`
## Your Task
### Step 1: Identify Notes to Process
```bash
# If single file
Read the specified file
@@ -24,6 +28,7 @@ Find all .md files in folder
### Step 2: Analyze Note Content
For each note, examine:
- Main topics and themes
- Note type (meeting, daily, reference, project)
- Key entities (people, projects, dates)
@@ -35,22 +40,24 @@ For each note, examine:
#### Standard Properties by Note Type
**Meeting Notes:**
```yaml
---
title: [Descriptive meeting title]
date: YYYY-MM-DD
type: meeting
attendees: ["Person 1", "Person 2"]
attendees: ['Person 1', 'Person 2']
project: Project Name
tags: [meeting, project-name]
action_items:
- "Action item 1"
- "Action item 2"
action_items:
- 'Action item 1'
- 'Action item 2'
status: complete
---
```
**Daily Notes:**
```yaml
---
title: Daily Note - YYYY-MM-DD
@@ -58,12 +65,13 @@ date: YYYY-MM-DD
type: daily-note
tags: [daily]
highlights:
- "Key event or thought"
- 'Key event or thought'
mood: productive
---
```
**Reference/Article Notes:**
```yaml
---
title: [Article or concept title]
@@ -77,13 +85,14 @@ key_concepts: [concept1, concept2]
```
**Project Notes:**
```yaml
---
title: [Project Name - Component]
type: project
status: in-progress
deadline: YYYY-MM-DD
stakeholders: ["Person 1", "Team 2"]
stakeholders: ['Person 1', 'Team 2']
tags: [project, area]
priority: high
---
@@ -92,6 +101,7 @@ priority: high
### Step 4: Apply Properties
For each note:
1. Check for existing frontmatter
2. Merge new properties (don't duplicate)
3. Fix any deprecated formats:
@@ -106,22 +116,23 @@ For each note:
# Format:
---
property: value
list_property: ["item1", "item2"]
list_property: ['item1', 'item2']
date_property: YYYY-MM-DD
linked_property: "[[Note Name]]"
linked_property: '[[Note Name]]'
---
[Original content]
```
## Property Guidelines
### Naming Conventions
- Use lowercase with underscores: `date_created`, `action_items`
- Be consistent with existing vault patterns
- Prefer clear over clever names
### Value Types
- **Text**: Simple strings, use quotes for links
- **List**: Arrays for multiple values
- **Date**: ISO format (YYYY-MM-DD)
@@ -129,6 +140,7 @@ linked_property: "[[Note Name]]"
- **Checkbox**: For boolean states
### Quality Checks
- ✅ Valid YAML syntax
- ✅ No duplicate properties
- ✅ Appropriate property types
@@ -138,18 +150,23 @@ linked_property: "[[Note Name]]"
## Special Cases
### Untitled Notes
Generate title from:
1. First heading if exists
2. First paragraph summary
3. Main topic/concept discussed
### Bulk Processing
When processing folders:
- Maintain consistency across similar notes
- Use same property names for same concepts
- Report summary of changes made
### Existing Properties
- Preserve valid existing properties
- Update deprecated formats
- Merge new properties carefully
@@ -158,17 +175,19 @@ When processing folders:
## Examples
### Before:
```markdown
Had a great meeting with the team about Q1 planning...
```
### After:
```markdown
---
title: Q1 Planning Team Meeting
date: 2025-09-02
type: meeting
attendees: ["Team"]
attendees: ['Team']
project: Q1 Planning
tags: [meeting, planning, q1-2025]
status: complete
@@ -177,4 +196,5 @@ status: complete
Had a great meeting with the team about Q1 planning...
```
Remember: Properties should enhance organization, not clutter. Only add what provides value for finding and connecting notes.
Remember: Properties should enhance organization, not clutter. Only add what
provides value for finding and connecting notes.
+2 -4
View File
@@ -60,9 +60,7 @@ Brief description of what this command does.
## Example Usage
\`\`\`
claude run [command-name] [arguments]
\`\`\`
\`\`\` claude run [command-name] [arguments] \`\`\`
```
## Best Practices
@@ -74,4 +72,4 @@ claude run [command-name] [arguments]
- Specify output format
- List needed tools in frontmatter
Let me help you create your command!
Let me help you create your command!
+9 -2
View File
@@ -32,30 +32,37 @@ Create or update a daily note with:
# Daily Review - [Date]
## Accomplished
- ✓ [Completed item 1]
- ✓ [Completed item 2]
## Progress Made
- [Project/Area]: [What moved forward]
- [Project/Area]: [What moved forward]
## Insights
- [Key realization or connection]
- [Important learning]
## Blocked/Stuck
- [What didn't progress and why]
## Discovered Questions
- [New question that emerged]
- [Thing to research]
## Tomorrow's Focus
1. [Priority 1]
2. [Priority 2]
2. [Priority 2]
3. [Priority 3]
## Open Loops
- [ ] [Thing to remember]
- [ ] [Person to follow up with]
- [ ] [Idea to develop]
@@ -66,4 +73,4 @@ Create or update a daily note with:
- Move completed project tasks to archive
- Update project status notes
- Link related discoveries
- Flag items needing attention
- Flag items needing attention
+17 -6
View File
@@ -10,33 +10,39 @@ Remove AI-generated patterns and restore natural human voice to your writing.
## Processing: $ARGUMENTS
I'll create a de-AI-ified version of your text that sounds more human and less machine-generated.
I'll create a de-AI-ified version of your text that sounds more human and less
machine-generated.
## What Gets Removed
### 1. Overused Transitions
- "Moreover," "Furthermore," "Additionally," "Nevertheless"
- Excessive "However" usage
- "While X, Y" openings
### 2. AI Clichés
- "In today's fast-paced world"
- "Let's dive deep"
- "Unlock your potential"
- "Harness the power of"
### 3. Hedging Language
- "It's important to note"
- "It's worth mentioning"
- Vague quantifiers: "various," "numerous," "myriad"
### 4. Corporate Buzzwords
- "utilize" → "use"
- "facilitate" → "help"
- "optimize" → "improve"
- "leverage" → "use"
### 5. Robotic Patterns
- Rhetorical questions followed by immediate answers
- Obsessive parallel structures
- Always using exactly three examples
@@ -45,12 +51,14 @@ I'll create a de-AI-ified version of your text that sounds more human and less m
## What Gets Added
### Natural Voice
- Varied sentence lengths
- Conversational tone
- Direct statements
- Specific examples
### Human Rhythm
- Natural transitions
- Confident assertions
- Personal perspective
@@ -66,16 +74,19 @@ I'll create a de-AI-ified version of your text that sounds more human and less m
## Output
You'll get:
- A new file with natural human voice
- Change log showing what was fixed
- List of places needing specific examples
## Example Transformations
**Before (AI):**
"In today's rapidly evolving digital landscape, it's crucial to understand that leveraging AI effectively isn't just about utilizing cutting-edge technology—it's about harnessing its transformative potential to unlock unprecedented opportunities."
**Before (AI):** "In today's rapidly evolving digital landscape, it's crucial to
understand that leveraging AI effectively isn't just about utilizing
cutting-edge technology—it's about harnessing its transformative potential to
unlock unprecedented opportunities."
**After (Human):**
"AI works best when you use it for specific tasks. Focus on what it does well: writing code, analyzing data, and answering questions."
**After (Human):** "AI works best when you use it for specific tasks. Focus on
what it does well: writing code, analyzing data, and answering questions."
Let me de-AI-ify your text!
Let me de-AI-ify your text!
+5 -2
View File
@@ -1,6 +1,7 @@
# Inbox Processor
Help organize and process items in the 00_Inbox folder according to the PARA method.
Help organize and process items in the 00_Inbox folder according to the PARA
method.
## Task
@@ -23,6 +24,7 @@ Review all notes in `00_Inbox/` and help categorize them:
- **→ Delete**: No value, redundant, or temporary
4. **Suggest Actions**
```
File: [filename]
Type: [detected type]
@@ -39,6 +41,7 @@ Review all notes in `00_Inbox/` and help categorize them:
## Output Format
Provide a clear action plan:
1. Items to move (with destinations)
2. Items to combine or link
3. Items to delete
@@ -48,4 +51,4 @@ Provide a clear action plan:
- Some items legitimately belong in the Inbox (daily notes, quick captures)
- Don't over-organize - sometimes "good enough" is perfect
- Look for opportunities to connect ideas, not just file them
- Look for opportunities to connect ideas, not just file them
+169 -113
View File
@@ -1,17 +1,22 @@
---
name: init-bootstrap
description: Interactive setup wizard that helps new users create a personalized CLAUDE.md file based on their Obsidian workflow preferences
description:
Interactive setup wizard that helps new users create a personalized CLAUDE.md
file based on their Obsidian workflow preferences
allowed-tools: [Read, Write, MultiEdit, Bash, Task]
argument-hint: "(optional) path to existing vault or 'new' for fresh setup"
---
# Initialize Bootstrap Configuration
This command helps you create a personalized CLAUDE.md configuration file by asking questions about your Obsidian workflow and preferences.
This command helps you create a personalized CLAUDE.md configuration file by
asking questions about your Obsidian workflow and preferences.
## Task
Read the CLAUDE-BOOTSTRAP.md template and interactively gather information about the user's:
Read the CLAUDE-BOOTSTRAP.md template and interactively gather information about
the user's:
- Existing vault structure (if any)
- Workflow preferences
- Note-taking style
@@ -36,7 +41,8 @@ Then generate a customized CLAUDE.md file tailored to their needs.
- 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
@@ -46,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
@@ -61,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)
@@ -91,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)
@@ -122,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": [
@@ -164,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)
@@ -172,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
@@ -195,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
@@ -219,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
@@ -232,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]`
@@ -253,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
@@ -271,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
@@ -293,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.
@@ -347,34 +388,33 @@ git remote remove origin # Disconnect from claudesidian repo
# 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*
_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*
📂 **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*
🎯 **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
✅ 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
@@ -399,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
@@ -406,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
@@ -452,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
@@ -467,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
@@ -480,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
@@ -494,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
@@ -503,70 +552,77 @@ Is there anything else I should know about your work or interests?
User: I'm really interested in how AI can augment thinking, not just writing
Got it! I'll remember that you focus on AI as a thinking tool, not just a writing assistant.
Got it! I'll remember that you focus on AI as a thinking tool, not just a
writing assistant.
3. **What will you primarily use this vault for?**
(research, writing, project management, daily notes, knowledge base, or combination?)
3. **What will you primarily use this vault for?** (research, writing, project
management, daily notes, knowledge base, or combination?)
User: I'll use it for research and writing, plus managing client projects
Assistant: Great! I'll configure your vault for research, writing, and client project management.
Assistant: Great! I'll configure your vault for research, writing, and client
project management.
2. **What specific projects are you currently working on?**
(I'll create folders for each in 01_Projects)
2. **What specific projects are you currently working on?** (I'll create folders
for each in 01_Projects)
User: I'm writing a book about productivity systems, building a SaaS app, and planning a conference talk
User: I'm writing a book about productivity systems, building a SaaS app, and
planning a conference talk
Assistant: Perfect! I'll set up project folders for:
- 01_Projects/Book - Productivity Systems/
- 01_Projects/SaaS App Development/
- 01_Projects/Conference Talk/
3. **What ongoing areas of responsibility do you maintain?**
(These go in 02_Areas - things without an end date)
- 01_Projects/Book - Productivity Systems/
- 01_Projects/SaaS App Development/
- 01_Projects/Conference Talk/
3. **What ongoing areas of responsibility do you maintain?** (These go in
02_Areas - things without an end date)
User: My newsletter, health & fitness, personal finances, and family activities
Assistant: I'll create area folders for:
- 02_Areas/Newsletter/
- 02_Areas/Health & Fitness/
- 02_Areas/Finances/
- 02_Areas/Family/
4. **What topics do you frequently research or reference?**
(I'll organize these in 03_Resources)
- 02_Areas/Newsletter/
- 02_Areas/Health & Fitness/
- 02_Areas/Finances/
- 02_Areas/Family/
4. **What topics do you frequently research or reference?** (I'll organize these
in 03_Resources)
User: AI tools, productivity methods, SaaS metrics, and writing techniques
Assistant: Setting up resource folders for:
- 03_Resources/AI Tools/
- 03_Resources/Productivity Methods/
- 03_Resources/SaaS Metrics/
- 03_Resources/Writing Techniques/
- 03_Resources/AI Tools/
- 03_Resources/Productivity Methods/
- 03_Resources/SaaS Metrics/
- 03_Resources/Writing Techniques/
[Continues with questions...]
**Gemini Vision Setup**
Gemini Vision is already included in claudesidian! It can analyze images, PDFs, and videos in your vault.
To activate it, you just need a free Google API key (takes 30 seconds).
Would you like to set it up now? (yes/no/later)
**Gemini Vision Setup** Gemini Vision is already included in claudesidian! It
can analyze images, PDFs, and videos in your vault. To activate it, you just
need a free Google API key (takes 30 seconds). Would you like to set it up now?
(yes/no/later)
User: later
No problem! You can set it up anytime by running `/setup-gemini` when you're ready.
No problem! You can set it up anytime by running `/setup-gemini` when you're
ready.
**Firecrawl Setup**
Firecrawl is a game-changer for research! Save any article or website directly to your vault as markdown.
Perfect for building a permanent, searchable research library.
Would you like to set it up? (yes/no/later)
**Firecrawl Setup** Firecrawl is a game-changer for research! Save any article
or website directly to your vault as markdown. Perfect for building a permanent,
searchable research library. Would you like to set it up? (yes/no/later)
User: yes
Great choice! Firecrawl will transform how you collect research.
Assistant: Excellent! Here's how to get your API key:
1. Go to https://aistudio.google.com/apikey
2. Click "Create API Key"
3. Copy the key (starts with AIzaSy...)
Once you have it, paste it here and I'll configure everything for you.
Once you have it, paste it here and I'll configure everything for you.
+22 -6
View File
@@ -1,13 +1,19 @@
---
name: release
description: Automatically bump version, update changelog, commit, tag, and push a new release based on recent changes
description:
Automatically bump version, update changelog, commit, tag, and push a new
release based on recent changes
allowed-tools: [Read, Write, Edit, MultiEdit, Bash, Grep]
argument-hint: "(optional) 'major', 'minor', 'patch', or leave blank for auto-detection"
argument-hint:
"(optional) 'major', 'minor', 'patch', or leave blank for auto-detection"
---
# Release Command
Automates the entire release process: analyzes recent commits to determine version bump type, updates version in package.json, moves unreleased changelog entries to the new version, commits everything, creates a git tag, and pushes to GitHub.
Automates the entire release process: analyzes recent commits to determine
version bump type, updates version in package.json, moves unreleased changelog
entries to the new version, commits everything, creates a git tag, and pushes to
GitHub.
## Task
@@ -62,11 +68,14 @@ Automates the entire release process: analyzes recent commits to determine versi
### Semantic Versioning (MAJOR.MINOR.PATCH)
**Quick Decision Guide:**
- Can users do something they couldn't do before? → **MINOR**
- Did something that worked break? → **MAJOR** (if breaking) or **PATCH** (if fixing)
- Did something that worked break? → **MAJOR** (if breaking) or **PATCH** (if
fixing)
- Did something that worked get better? → **PATCH**
**MAJOR** (1.0.0 → 2.0.0):
- Breaking changes that require users to change their code/config
- Removing features or commands
- Changing command syntax or behavior incompatibly
@@ -74,6 +83,7 @@ Automates the entire release process: analyzes recent commits to determine versi
- Commits with "!" after type (e.g., "feat!:")
**MINOR** (1.0.0 → 1.1.0):
- **NEW capabilities** added (not enhancements to existing features)
- Making something possible that wasn't possible before
- New commands, new tools, new integrations
@@ -88,12 +98,14 @@ Automates the entire release process: analyzes recent commits to determine versi
- Enabling a feature to work offline when it required internet before
**PATCH** (1.0.0 → 1.0.1):
- Bug fixes and minor improvements
- Enhancements to existing features (that already worked)
- Performance improvements
- Documentation updates
- Refactoring without changing behavior
- Commits with "fix:", "docs:", "style:", "refactor:", "perf:", "test:", "chore:"
- Commits with "fix:", "docs:", "style:", "refactor:", "perf:", "test:",
"chore:"
- Examples:
- Making an existing command smarter (but not enabling new use cases)
- Improving error messages
@@ -104,18 +116,22 @@ Automates the entire release process: analyzes recent commits to determine versi
### Commit Message Best Practices
**Use "feat:" only for NEW features:**
-`feat: add vault import capability`
-`feat: enhance vault import` (should be `fix:` or `refactor:`)
**Use "fix:" for improvements and corrections:**
-`fix: improve vault detection accuracy`
-`fix: correct file counting in init-bootstrap`
**Use "refactor:" for code improvements:**
-`refactor: enhance profile building with URL fetching`
-`refactor: make init-bootstrap questions smarter`
**Use "perf:" for performance improvements:**
-`perf: optimize vault analysis for large vaults`
## Example Usage
@@ -165,4 +181,4 @@ claude run release major
- Dry run mode: Show what would happen without making changes
- Confirmation prompt before pushing
- Validation of version format
- Check for existing tags before creating
- Check for existing tags before creating
+9 -3
View File
@@ -1,6 +1,7 @@
# Research Assistant
Conduct thorough research on topics by searching the vault and synthesizing findings.
Conduct thorough research on topics by searching the vault and synthesizing
findings.
## Process
@@ -27,31 +28,36 @@ Conduct thorough research on topics by searching the vault and synthesizing find
# Research Summary: [Topic]
## Existing Knowledge
- What's already in the vault
- Key insights from previous work
## Key Themes
1. Theme 1
- Supporting notes: [[note1]], [[note2]]
- Key insight: ...
2. Theme 2
- Supporting notes: [[note3]], [[note4]]
- Key insight: ...
## Contradictions/Tensions
- Where ideas conflict
- Unresolved questions
## Gaps
- What's missing
- What to research next
## Connections
- Related topics: [[topic1]], [[topic2]]
- Surprising links: ...
## Recommended Next Steps
1. Specific research needed
2. Questions to explore
3. Experiments to try
@@ -62,4 +68,4 @@ Conduct thorough research on topics by searching the vault and synthesizing find
- Cast a wide net initially, then focus
- Look for surprising connections
- Don't ignore contradictions - they're often where insights live
- Always suggest concrete next actions
- Always suggest concrete next actions
+13 -6
View File
@@ -1,13 +1,19 @@
# Thinking Partner
You are a collaborative thinking partner specializing in helping people explore complex problems. Your role is to facilitate thinking through careful questioning and exploration, not to rush toward solutions.
You are a collaborative thinking partner specializing in helping people explore
complex problems. Your role is to facilitate thinking through careful
questioning and exploration, not to rush toward solutions.
## Core Behaviors
1. **Ask before answering** - Lead with questions that help clarify and deepen understanding
2. **Track insights** - Maintain a running log of key discoveries and connections
3. **Resist solutioning** - Stay in exploration mode until explicitly asked to move forward
4. **Connect ideas** - Help identify patterns and relationships across different notes
1. **Ask before answering** - Lead with questions that help clarify and deepen
understanding
2. **Track insights** - Maintain a running log of key discoveries and
connections
3. **Resist solutioning** - Stay in exploration mode until explicitly asked to
move forward
4. **Connect ideas** - Help identify patterns and relationships across different
notes
5. **Surface assumptions** - Gently challenge implicit beliefs and assumptions
## Workflow
@@ -34,4 +40,5 @@ When engaged as a thinking partner:
## Remember
The goal is not to have answers but to help discover them. Your value is in the quality of exploration, not the speed of resolution.
The goal is not to have answers but to help discover them. Your value is in the
quality of exploration, not the speed of resolution.
+155 -108
View File
@@ -1,13 +1,19 @@
---
name: upgrade
description: Intelligently upgrade claudesidian with new features while preserving user customizations using AI-powered semantic analysis
description:
Intelligently upgrade claudesidian with new features while preserving user
customizations using AI-powered semantic analysis
allowed-tools: [Read, Write, Edit, MultiEdit, Bash, WebFetch, Grep, Glob]
argument-hint: "(optional) 'check' to preview changes, 'force' to skip confirmations"
argument-hint:
"(optional) 'check' to preview changes, 'force' to skip confirmations"
---
# Smart Upgrade Command
Intelligently upgrades your claudesidian installation by fetching the latest release from GitHub and using AI-powered semantic analysis to merge new features with your existing customizations. Preserves user intent while adding new capabilities.
Intelligently upgrades your claudesidian installation by fetching the latest
release from GitHub and using AI-powered semantic analysis to merge new features
with your existing customizations. Preserves user intent while adding new
capabilities.
## Task
@@ -21,155 +27,173 @@ Intelligently upgrades your claudesidian installation by fetching the latest rel
## Process
### 1. **Version Check & Setup**
- Get current version from package.json
- Create timestamped backup in `.backup/upgrade-YYYY-MM-DD-HHMMSS/`
- Clone latest claudesidian to temp directory (doesn't affect user's repo):
```bash
# Get fresh copy in .tmp dir (hidden from Obsidian) - user's repo stays disconnected
git clone --depth=1 --branch=main https://github.com/heyitsnoah/claudesidian.git .tmp/claudesidian-upgrade
```
- Now we have latest version to compare against
- Get current version from package.json
- Create timestamped backup in `.backup/upgrade-YYYY-MM-DD-HHMMSS/`
- Clone latest claudesidian to temp directory (doesn't affect user's repo):
```bash
# Get fresh copy in .tmp dir (hidden from Obsidian) - user's repo stays disconnected
git clone --depth=1 --branch=main https://github.com/heyitsnoah/claudesidian.git .tmp/claudesidian-upgrade
```
- Now we have latest version to compare against
### 2. **Create Upgrade Checklist**
- Compare system files between current directory and .tmp/claudesidian-upgrade/:
```bash
# Find all system files that differ
diff -qr . .tmp/claudesidian-upgrade/ --include="*.md" --include="*.sh" --include="*.json" |
grep -E '(\.claude/|\.scripts/|package\.json|CHANGELOG\.md|README\.md)' |
grep -v '(00_|01_|02_|03_|04_|05_|06_|\.obsidian|CLAUDE\.md)'
```
- Create checklist of files that need review
- Explicitly EXCLUDE:
- User content folders (00_Inbox, 01_Projects, etc.)
- User's CLAUDE.md (their personalized version)
- vault-config.json (user's vault configuration)
- .obsidian/ (user's Obsidian settings)
- Any .md files in the root except README and CHANGELOG
- Create `.upgrade-checklist.md` with only system files that differ
- Mark each file with status: `[ ] pending`, `[x] updated`, `[-] skipped`
- Group files by type for easier review:
```markdown
## Commands (12 files)
[ ] .claude/commands/init-bootstrap.md
[ ] .claude/commands/release.md
[ ] .claude/commands/thinking-partner.md
...
## Settings (2 files)
[ ] .claude/settings.json
[ ] .claude/settings.local.json
- Compare system files between current directory and .tmp/claudesidian-upgrade/:
```bash
# Find all system files that differ
diff -qr . .tmp/claudesidian-upgrade/ --include="*.md" --include="*.sh" --include="*.json" |
grep -E '(\.claude/|\.scripts/|package\.json|CHANGELOG\.md|README\.md)' |
grep -v '(00_|01_|02_|03_|04_|05_|06_|\.obsidian|CLAUDE\.md)'
```
- Create checklist of files that need review
- Explicitly EXCLUDE:
- User content folders (00_Inbox, 01_Projects, etc.)
- User's CLAUDE.md (their personalized version)
- vault-config.json (user's vault configuration)
- .obsidian/ (user's Obsidian settings)
- Any .md files in the root except README and CHANGELOG
- Create `.upgrade-checklist.md` with only system files that differ
- Mark each file with status: `[ ] pending`, `[x] updated`, `[-] skipped`
- Group files by type for easier review:
## Core Files (3 files)
[ ] package.json
[ ] CHANGELOG.md
[ ] README.md
```
```markdown
## Commands (12 files)
[ ] .claude/commands/init-bootstrap.md [ ] .claude/commands/release.md [ ]
.claude/commands/thinking-partner.md ...
## Settings (2 files)
[ ] .claude/settings.json [ ] .claude/settings.local.json
## Core Files (3 files)
[ ] package.json [ ] CHANGELOG.md [ ] README.md
```
### 3. **File-by-File Review**
**⚠️ CRITICAL IMPLEMENTATION REQUIREMENT:**
- **NEVER blindly overwrite files with `cat > file` or `cp`**
- **ALWAYS show diffs to the user first**
- **ALWAYS ask for confirmation before replacing files**
- **Skipping these steps can lose user customizations!**
**⚠️ CRITICAL IMPLEMENTATION REQUIREMENT:**
- **NEVER blindly overwrite files with `cat > file` or `cp`**
- **ALWAYS show diffs to the user first**
- **ALWAYS ask for confirmation before replacing files**
- **Skipping these steps can lose user customizations!**
For EACH file in the checklist:
1. Read current checklist status from `.upgrade-checklist.md`
2. **MANDATORY: Show the diff between local and upstream**:
```bash
# ALWAYS show this to the user!
diff -u current/file .tmp/claudesidian-upgrade/file
```
3. Determine update strategy:
- **No local changes**: Direct replace from upstream
- **Never update**: User's CLAUDE.md, vault-config.json, .mcp.json
- **Local changes detected**: Ask user:
For EACH file in the checklist:
1. Read current checklist status from `.upgrade-checklist.md`
2. **MANDATORY: Show the diff between local and upstream**:
```bash
# ALWAYS show this to the user!
diff -u current/file .tmp/claudesidian-upgrade/file
```
3. Determine update strategy:
- **No local changes**: Direct replace from upstream
- **Never update**: User's CLAUDE.md, vault-config.json, .mcp.json
- **Local changes detected**: Ask user:
```
File: .claude/commands/thinking-partner.md has local modifications
File: .claude/commands/thinking-partner.md has local modifications
Options:
1. Keep your version (skip update)
2. Take upstream version (lose your changes)
3. View diff and decide
4. Try to merge both (AI-assisted)
Options:
1. Keep your version (skip update)
2. Take upstream version (lose your changes)
3. View diff and decide
4. Try to merge both (AI-assisted)
Choice (1/2/3/4): _
```
4. Apply the chosen strategy
5. **CRITICAL: Update the checklist file immediately**:
```markdown
[ ] .claude/commands/init-bootstrap.md → becomes → [x] .claude/commands/init-bootstrap.md
Choice (1/2/3/4): _
```
6. Save `.upgrade-checklist.md` after EVERY file update
7. Move to next file
4. Apply the chosen strategy
5. **CRITICAL: Update the checklist file immediately**:
```markdown
[ ] .claude/commands/init-bootstrap.md → becomes → [x]
.claude/commands/init-bootstrap.md
```
6. Save `.upgrade-checklist.md` after EVERY file update
7. Move to next file
### 4. **Update Types**
- **Safe to replace**: `.claude/commands/*.md`, `.claude/agents/*.md`, `.scripts/*`
- **Needs review**: `package.json` (preserve user's custom scripts)
- **Never touch**: User content folders, CLAUDE.md, API configs
- **Safe to replace**: `.claude/commands/*.md`, `.claude/agents/*.md`,
`.scripts/*`
- **Needs review**: `package.json` (preserve user's custom scripts)
- **Never touch**: User content folders, CLAUDE.md, API configs
### 5. **Progress Tracking**
- Use TodoWrite tool to track progress alongside the checklist
- Save progress after each file in `.upgrade-checklist.md`
- **MUST mark items in checklist**:
- `[x]` = completed
- `[-]` = skipped (user customization)
- `[ ]` = still pending
- If interrupted, can resume from where you left off
- Show progress: "Updating file 5 of 23..."
- Clear indication of what's been done and what's remaining
- Use TodoWrite tool to track progress alongside the checklist
- Save progress after each file in `.upgrade-checklist.md`
- **MUST mark items in checklist**:
- `[x]` = completed
- `[-]` = skipped (user customization)
- `[ ]` = still pending
- If interrupted, can resume from where you left off
- Show progress: "Updating file 5 of 23..."
- Clear indication of what's been done and what's remaining
### 6. **Verification Check**
- Re-check all system files against the checklist
- Compare with checklist to identify:
- Files marked `[ ]` pending = likely missed (problem)
- Files marked `[-]` skipped = intentionally kept different (fine)
- Files marked `[x]` updated but still in diff = merge issues or user edits (review)
- Show verification results:
```
✅ All required files updated successfully
️ 2 files intentionally kept with user customizations:
- .claude/commands/thinking-partner.md (user's concise style)
- package.json (user's custom scripts preserved)
- or -
⚠️ Warning: 2 files appear to be missed (still marked pending):
- .claude/commands/release.md
- .scripts/vault-stats.sh
```
- Only flag as problem if files are still marked `[ ]` pending in checklist
- Re-check all system files against the checklist
- Compare with checklist to identify:
- Files marked `[ ]` pending = likely missed (problem)
- Files marked `[-]` skipped = intentionally kept different (fine)
- Files marked `[x]` updated but still in diff = merge issues or user edits
(review)
- Show verification results:
```
✅ All required files updated successfully
️ 2 files intentionally kept with user customizations:
- .claude/commands/thinking-partner.md (user's concise style)
- package.json (user's custom scripts preserved)
- or -
⚠️ Warning: 2 files appear to be missed (still marked pending):
- .claude/commands/release.md
- .scripts/vault-stats.sh
```
- Only flag as problem if files are still marked `[ ]` pending in checklist
### 7. **Final Steps**
- Update version in package.json
- Verify all commands work
- Clean up temp directory: `rm -rf .tmp/claudesidian-upgrade`
- Save final checklist for reference (shows what was updated vs skipped)
- Show summary of what was updated
- Update version in package.json
- Verify all commands work
- Clean up temp directory: `rm -rf .tmp/claudesidian-upgrade`
- Save final checklist for reference (shows what was updated vs skipped)
- Show summary of what was updated
## Update Categories
### 🤖 AI-Powered Intelligent Merge
**Commands** (`.claude/commands/*.md`):
- Analyze user's prompt style, output preferences, workflow modifications
- Merge new features with existing customizations
- Preserve user's tone, structure, and specific requirements
**Agents** (`.claude/agents/*.md`):
- Understand user's interaction preferences
- Combine new capabilities with existing personality
- Maintain user's established workflows
**Templates** (`06_Metadata/Templates/*.md`):
- Preserve custom fields and structure
- Add new template features
- Maintain user's formatting preferences
### ⚡ Automatic Safe Updates
- **New commands/agents**: Purely additive, no conflicts
- **Scripts** (`.scripts/*`): Utility functions, safe to replace
- **Dependencies** (`package.json`): Security and feature updates
- **Documentation**: README, CONTRIBUTING updates
### 🛡️ Never Modified
- **User content**: All `00_*` through `06_*` folders (except templates)
- **Personal config**: User's `CLAUDE.md`
- **API keys**: `.mcp.json`, environment variables
@@ -182,6 +206,7 @@ When Claude detects conflicts:
### Example Scenarios:
**Scenario 1: Command Enhancement**
```
📝 thinking-partner command has updates:
@@ -202,6 +227,7 @@ Options:
```
**Scenario 2: Template Updates**
```
📋 Project Template has changes:
@@ -220,27 +246,33 @@ Apply merge? (y/n/preview)
## Command Usage
### Preview Mode (Recommended First Run)
```
/upgrade check
```
- Shows what would be updated
- Displays intelligent merge previews
- No changes made to files
- Safe to run anytime
### Interactive Upgrade
```
/upgrade
```
- Step-by-step confirmation for each change
- Shows before/after for modified files
- Allows selective application of updates
- Creates automatic backups
### Batch Upgrade (Advanced)
```
/upgrade force
```
- Applies all safe updates automatically
- Still prompts for complex merges
- Faster for users comfortable with the process
@@ -249,11 +281,13 @@ Apply merge? (y/n/preview)
## Safety Features
### Automatic Backups
- Complete backup before any changes: `.backup/upgrade-[timestamp]/`
- Individual file backups for each modification
- Backup includes current git state and uncommitted changes
### Rollback Support
```
# If upgrade causes issues:
/rollback-upgrade [timestamp]
@@ -261,12 +295,14 @@ Apply merge? (y/n/preview)
```
### Verification Steps
- Post-upgrade functionality testing
- Command validation (runs test commands)
- MCP server connectivity check
- Git repository integrity verification
### Incremental Application
- Updates applied one file at a time
- Validation after each critical change
- Stops on first error with clear diagnostics
@@ -275,23 +311,28 @@ Apply merge? (y/n/preview)
## Common Pitfalls to Avoid
### ⚠️ Selective Updates Problem
**Never cherry-pick files based only on release notes!** This leads to:
- Missing critical command updates
- Incomplete feature implementations
- Broken dependencies between files
- Users not getting all improvements
**Always use `git diff HEAD upstream/main --name-only`** to get the complete list of changed files, then update ALL relevant files systematically.
**Always use `git diff HEAD upstream/main --name-only`** to get the complete
list of changed files, then update ALL relevant files systematically.
## Error Handling
### Common Scenarios
- **No internet connection**: Graceful failure with offline options
- **GitHub API rate limits**: Intelligent retry with backoff
- **Merge conflicts**: Clear explanation and manual resolution options
- **Permission issues**: Helpful guidance on fixing file permissions
### Recovery Options
- **Partial failure**: Continue from last successful step
- **Complete failure**: Full rollback to pre-upgrade state
- **Git conflicts**: Merge upstream changes with local commits
@@ -300,19 +341,23 @@ Apply merge? (y/n/preview)
## Advanced Features
### Custom Merge Rules
Users can create `.upgrade-rules.json` to specify:
- Files to always skip
- Custom merge preferences
- Automatic approval for specific change types
- Backup retention policies
### Integration with Git
- Commits each major change separately
- Meaningful commit messages describing updates
- Preserves user's branch structure
- Handles git conflicts intelligently
### Selective Updates
```
/upgrade commands-only # Update just commands
/upgrade agents-only # Update just agents
@@ -510,4 +555,6 @@ Choice (1/2/3) > 1
- User customizations preserved where intended
```
This intelligent upgrade system leverages Claude's semantic understanding to provide the smoothest possible upgrade experience while ensuring no user customizations are lost.
This intelligent upgrade system leverages Claude's semantic understanding to
provide the smoothest possible upgrade experience while ensuring no user
customizations are lost.
+15 -3
View File
@@ -35,50 +35,62 @@ Create a weekly synthesis note:
# Weekly Synthesis - Week of [Date]
## Week at a Glance
- Notes created: [X]
- Projects active: [List]
- Major accomplishments: [List]
## Key Themes
### Theme 1: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
### Theme 2: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
## Major Insights
1. [Insight with context]
2. [Insight with context]
## Progress by Project
### [Project Name]
- What advanced:
- What advanced:
- What's blocked:
- Next week's focus:
## Questions Emerged
- [Question 1 - and why it matters]
- [Question 2 - and why it matters]
## Energy Audit
- What gave energy:
- What gave energy:
- What drained energy:
- What to adjust:
## Connections Made
- [Note A] ←→ [Note B]: [Why significant]
- [Concept X] ←→ [Concept Y]: [New understanding]
## Next Week's Intentions
1. [Primary focus]
2. [Secondary focus]
3. [Thing to explore]
## To Process
- Inbox items: [count]
- Orphaned notes: [list]
- Missing connections: [identified]
@@ -89,4 +101,4 @@ Create a weekly synthesis note:
- Archive completed projects
- Clean up inbox
- Update project status
- Plan next week's focus
- Plan next week's focus
@@ -5,6 +5,7 @@
## Prerequisites Check
Run these commands to verify you have everything needed:
```bash
node --version # Should be v22+
pnpm --version # Should be installed
@@ -12,19 +13,22 @@ claude --version # Claude Code should be installed
```
If any are missing:
- Node.js: Install from [nodejs.org](https://nodejs.org/) (v22+)
- pnpm: `npm install -g pnpm`
- Claude Code: Download from [claude.ai/code](https://claude.ai/code)
## Step 1: Get Your Gemini API Key
1. Go to [https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)
1. Go to
[https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)
2. Click "Create API Key"
3. Copy the key (starts with `AIzaSy...`)
## Step 2: Set Up Environment Variable
### For Linux/macOS with Bash:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.bashrc
source ~/.bashrc
@@ -32,6 +36,7 @@ echo $GEMINI_API_KEY # Verify it shows your key
```
### For Linux/macOS with Zsh:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.zshrc
source ~/.zshrc
@@ -39,6 +44,7 @@ echo $GEMINI_API_KEY # Verify it shows your key
```
### For Windows PowerShell:
```powershell
[System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key-here', 'User')
# Restart PowerShell
@@ -50,11 +56,13 @@ $env:GEMINI_API_KEY # Verify it shows your key
**⚠️ CRITICAL: This step MUST be done before adding the MCP server!**
Navigate to your Obsidian vault:
```bash
cd ~/dev/02_Areas/Obsidian # Or wherever your vault is
```
Install the required dependencies:
```bash
# Install npm packages (REQUIRED - do this first!)
pnpm install
@@ -65,9 +73,12 @@ pnpm install
# - Other dependencies from package.json
```
**Common Error Fix**: If you see `Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'`, you forgot to run `pnpm install`!
**Common Error Fix**: If you see
`Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'`,
you forgot to run `pnpm install`!
**To hide node_modules from Obsidian** (optional but recommended):
1. Open Obsidian
2. Go to Settings → Files & Links → Excluded files
3. Click "Manage"
@@ -79,18 +90,21 @@ This keeps your vault clean while using standard Node.js module resolution.
## Step 4: Register the MCP Server
**For project-scoped installation (recommended for team use):**
```bash
# Add server to project (creates .mcp.json file)
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
**For user-scoped installation (personal use across all projects):**
```bash
# Add server to your user config
claude mcp add --scope user gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
After adding, you'll need to edit the `.mcp.json` file to add your API key:
```json
{
"mcpServers": {
@@ -107,6 +121,7 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
```
**IMPORTANT**:
- The command must be run from the Obsidian vault root directory
- You MUST have run `pnpm install` first
- The `.mcp.json` file is gitignored for security
@@ -114,15 +129,16 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
## Step 5: Verify It's Working
1. **Open a NEW Claude Code window** (critical - must be new):
```bash
cd ~/dev/Obsidian
claude
```
2. **Check the server is connected**:
Type `/mcp` in Claude
2. **Check the server is connected**: Type `/mcp` in Claude
You should see:
```
gemini-vision ✔ connected
```
@@ -137,11 +153,13 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### "gemini-vision failed" or not showing in /mcp
1. **MOST COMMON ISSUE - Dependencies not installed**:
```bash
# If you see: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'
# Run this:
pnpm install
```
Then reconnect the MCP server in Claude Code.
2. **Check API key is configured**:
@@ -150,21 +168,24 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
- The key should be in the format: `"GEMINI_API_KEY": "AIzaSy..."`
3. **Test server can run directly**:
```bash
export GEMINI_API_KEY="your-api-key-here"
node .claude/mcp-servers/gemini-vision.mjs
```
Should show: "🚀 Gemini Vision MCP Server running"
Press Ctrl+C to exit.
Should show: "🚀 Gemini Vision MCP Server running" Press Ctrl+C to exit.
4. **Re-add the server (for project scope)**:
```bash
claude mcp remove gemini-vision --scope project
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
# Then edit .mcp.json to add your API key
```
4. **Check logs**:
5. **Check logs**:
```bash
# Find log directory
ls ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-gemini-vision/
@@ -178,12 +199,15 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### "Cannot find module" errors
1. **Verify package.json exists**:
```bash
cat package.json
```
Should show @google/generative-ai and @modelcontextprotocol/sdk
2. **Reinstall dependencies**:
```bash
rm -rf node_modules pnpm-lock.yaml
pnpm install
@@ -197,9 +221,11 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
### Server runs but tools don't work
1. **Test API key directly**:
```bash
curl "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY"
```
Should return a list of models, not an error.
2. **Check file paths**:
@@ -211,6 +237,7 @@ After adding, you'll need to edit the `.mcp.json` file to add your API key:
Once working, you can use these in Claude:
### Image Analysis
```
# Analyze an image
Use gemini-vision to analyze 05 Attachments/screenshot.png
@@ -229,6 +256,7 @@ Use gemini-vision to analyze multiple: image1.png, image2.png, image3.png
```
### Video Analysis (NEW!)
```
# Analyze a local video file
Use gemini-vision to analyze video 05 Attachments/video.mp4
@@ -240,14 +268,15 @@ Use gemini-vision to analyze YouTube video https://www.youtube.com/watch?v=VIDEO
Use gemini-vision to analyze video file.mp4 and extract all visible text
```
**Note:** Video processing may take 30-60 seconds as files need to reach ACTIVE state before analysis. The server will automatically wait and show progress updates.
**Note:** Video processing may take 30-60 seconds as files need to reach ACTIVE
state before analysis. The server will automatically wait and show progress
updates.
### Supported Formats
**Images:** JPG, JPEG, PNG, GIF, BMP, WebP
**Videos:** MP4, AVI, MOV, WebM, MKV, WMV, FLV, 3GP, M4V
**Documents:** PDF, TXT, DOC, DOCX, ODT, RTF
**Special:** YouTube URLs (direct support without download)
**Images:** JPG, JPEG, PNG, GIF, BMP, WebP **Videos:** MP4, AVI, MOV, WebM, MKV,
WMV, FLV, 3GP, M4V **Documents:** PDF, TXT, DOC, DOCX, ODT, RTF **Special:**
YouTube URLs (direct support without download)
## Quick Reinstall (If Already Set Up Once)
@@ -282,4 +311,4 @@ Then open a new Claude window and test.
---
*Last tested: September 2025*
_Last tested: September 2025_
+14 -4
View File
@@ -4,7 +4,8 @@ Model Context Protocol servers extend Claude Code's capabilities.
## Gemini Vision MCP
Adds powerful image and document analysis capabilities using Google's Gemini model.
Adds powerful image and document analysis capabilities using Google's Gemini
model.
### Features
@@ -21,15 +22,17 @@ Adds powerful image and document analysis capabilities using Google's Gemini mod
- Create a free API key
2. **Add to Environment**
```bash
# Add to ~/.zshrc or ~/.bashrc
export GEMINI_API_KEY='your-key-here'
# Reload shell
source ~/.zshrc
```
3. **Install Dependencies**
```bash
pnpm install
```
@@ -53,24 +56,28 @@ Once configured, these commands become available in Claude Code:
### Usage Examples
**Analyze Screenshot**
```
Analyze the image at 05_Attachments/screenshot.png
and tell me what it contains.
```
**Process Multiple Images**
```
Compare all images in 05_Attachments/Organized/
and identify common themes.
```
**Extract Text**
```
Extract all text from the PDF at
Extract all text from the PDF at
05_Attachments/document.pdf
```
**Rename Images**
```
Suggest better names for all images
in 05_Attachments/ based on their content.
@@ -79,14 +86,17 @@ in 05_Attachments/ based on their content.
### Troubleshooting
**"GEMINI_API_KEY not found"**
- Make sure you've added the key to your shell profile
- Restart your terminal and Claude Code
**"File not found"**
- Use absolute paths or paths relative to vault root
- Check file permissions
**Rate Limits**
- Free tier: 15 requests per minute
- Consider upgrading for heavy usage
@@ -101,4 +111,4 @@ in 05_Attachments/ based on their content.
- [MCP Documentation](https://modelcontextprotocol.io)
- [Gemini API Docs](https://ai.google.dev)
- [Claude Code MCP Guide](https://claude.ai/docs/mcp)
- [Claude Code MCP Guide](https://claude.ai/docs/mcp)
+340 -263
View File
@@ -1,208 +1,246 @@
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListToolsRequestSchema,
CallToolRequestSchema
} from "@modelcontextprotocol/sdk/types.js";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { GoogleAIFileManager } from "@google/generative-ai/server";
import fs from "fs/promises";
import path from "path";
import os from "os";
import { GoogleGenerativeAI } from '@google/generative-ai'
import { GoogleAIFileManager } from '@google/generative-ai/server'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js'
import fs from 'node:fs/promises'
import os from 'node:os'
import path from 'node:path'
const apiKey = process.env.GEMINI_API_KEY;
const apiKey = process.env.GEMINI_API_KEY
if (!apiKey) {
console.error("❌ GEMINI_API_KEY environment variable is required");
console.error("");
console.error("To fix this:");
console.error("");
console.error("1. Get your API key from: https://aistudio.google.com/apikey");
console.error("");
console.error("2. Add to your shell profile:");
console.error(" For macOS/Linux (add to ~/.zshrc or ~/.bashrc):");
console.error(" export GEMINI_API_KEY='your-actual-api-key-here'");
console.error("");
console.error(" For Windows PowerShell:");
console.error(" [System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key', 'User')");
console.error("");
console.error("3. Reload your terminal:");
console.error(" source ~/.zshrc (or source ~/.bashrc)");
console.error("");
console.error("4. Restart Claude Code");
console.error("");
console.error("For detailed instructions, see GEMINI_VISION_SETUP.md");
process.exit(1);
console.error('❌ GEMINI_API_KEY environment variable is required')
console.error('')
console.error('To fix this:')
console.error('')
console.error('1. Get your API key from: https://aistudio.google.com/apikey')
console.error('')
console.error('2. Add to your shell profile:')
console.error(' For macOS/Linux (add to ~/.zshrc or ~/.bashrc):')
console.error(" export GEMINI_API_KEY='your-actual-api-key-here'")
console.error('')
console.error(' For Windows PowerShell:')
console.error(
" [System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key', 'User')",
)
console.error('')
console.error('3. Reload your terminal:')
console.error(' source ~/.zshrc (or source ~/.bashrc)')
console.error('')
console.error('4. Restart Claude Code')
console.error('')
console.error('For detailed instructions, see GEMINI_VISION_SETUP.md')
process.exit(1)
}
const genAI = new GoogleGenerativeAI(apiKey);
const fileManager = new GoogleAIFileManager(apiKey);
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const genAI = new GoogleGenerativeAI(apiKey)
const fileManager = new GoogleAIFileManager(apiKey)
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' })
// Expand home directory in paths
function expandPath(filepath) {
if (filepath.startsWith("~/")) {
return path.join(os.homedir(), filepath.slice(2));
if (filepath.startsWith('~/')) {
return path.join(os.homedir(), filepath.slice(2))
}
return filepath;
return filepath
}
// Helper function to wait/sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
return new Promise((resolve) => setTimeout(resolve, ms))
}
// Upload file to Gemini
async function uploadFile(filePath) {
const expandedPath = expandPath(filePath);
const expandedPath = expandPath(filePath)
try {
await fs.access(expandedPath);
await fs.access(expandedPath)
} catch {
throw new Error(`File not found: ${filePath}`);
throw new Error(`File not found: ${filePath}`)
}
const ext = path.extname(expandedPath).toLowerCase();
const ext = path.extname(expandedPath).toLowerCase()
const mimeTypes = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.bmp': 'image/bmp',
'.webp': 'image/webp',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
'.doc': 'application/msword',
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.docx':
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.gif': 'image/gif',
'.jpeg': 'image/jpeg',
'.jpg': 'image/jpeg',
'.odt': 'application/vnd.oasis.opendocument.text',
'.pdf': 'application/pdf',
'.png': 'image/png',
'.rtf': 'application/rtf',
'.txt': 'text/plain',
'.webp': 'image/webp',
// Video formats
'.mp4': 'video/mp4',
'.avi': 'video/x-msvideo',
'.mov': 'video/quicktime',
'.webm': 'video/webm',
'.mkv': 'video/x-matroska',
'.wmv': 'video/x-ms-wmv',
'.flv': 'video/x-flv',
'.3gp': 'video/3gpp',
'.avi': 'video/x-msvideo',
'.flv': 'video/x-flv',
'.m4v': 'video/x-m4v',
};
'.mkv': 'video/x-matroska',
'.mov': 'video/quicktime',
'.mp4': 'video/mp4',
'.webm': 'video/webm',
'.wmv': 'video/x-ms-wmv',
}
const uploadResult = await fileManager.uploadFile(expandedPath, {
mimeType: mimeTypes[ext] || 'application/octet-stream',
});
})
let file = uploadResult.file;
let file = uploadResult.file
// For video files, poll until the file is in ACTIVE state
const videoExtensions = ['.mp4', '.avi', '.mov', '.webm', '.mkv', '.wmv', '.flv', '.3gp', '.m4v'];
const videoExtensions = [
'.mp4',
'.avi',
'.mov',
'.webm',
'.mkv',
'.wmv',
'.flv',
'.3gp',
'.m4v',
]
if (videoExtensions.includes(ext)) {
console.error(`Waiting for video file to process: ${path.basename(filePath)}`);
let attempts = 0;
const maxAttempts = 60; // Max 5 minutes (60 * 5 seconds)
console.error(
`Waiting for video file to process: ${path.basename(filePath)}`,
)
let attempts = 0
const maxAttempts = 60 // Max 5 minutes (60 * 5 seconds)
while (file.state !== 'ACTIVE' && attempts < maxAttempts) {
await sleep(5000); // Wait 5 seconds
attempts++;
await sleep(5000) // Wait 5 seconds
attempts++
// Get updated file status
const fileStatus = await fileManager.getFile(file.name);
file = fileStatus;
const fileStatus = await fileManager.getFile(file.name)
file = fileStatus
console.error(`Video processing status: ${file.state} (attempt ${attempts}/${maxAttempts})`);
console.error(
`Video processing status: ${file.state} (attempt ${attempts}/${maxAttempts})`,
)
if (file.state === 'FAILED') {
throw new Error(`Video processing failed for: ${filePath}`);
throw new Error(`Video processing failed for: ${filePath}`)
}
}
if (file.state !== 'ACTIVE') {
throw new Error(`Video processing timeout for: ${filePath}. File state: ${file.state}`);
throw new Error(
`Video processing timeout for: ${filePath}. File state: ${file.state}`,
)
}
console.error('Video file is ready for analysis');
console.error('Video file is ready for analysis')
}
return file;
return file
}
// Tool handlers
async function analyzeImage(args) {
const imagePath = args.image_path;
const prompt = args.prompt || "Describe this image in detail";
const file = await uploadFile(imagePath);
async function analyzeDocument(args) {
const documentPath = args.document_path
const prompt =
args.prompt || 'Analyze this document and provide a comprehensive summary'
const file = await uploadFile(documentPath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function analyzeImage(args) {
const imagePath = args.image_path
const prompt = args.prompt || 'Describe this image in detail'
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function analyzeMultiple(args) {
const imagePaths = args.image_paths;
const prompt = args.prompt || "Analyze these images";
const content = [prompt];
for (const imagePath of imagePaths) {
const file = await uploadFile(imagePath);
content.push({ fileData: { fileUri: file.uri, mimeType: file.mimeType }});
}
const result = await model.generateContent(content);
return result.response.text();
}
const imagePaths = args.image_paths
const prompt = args.prompt || 'Analyze these images'
async function extractText(args) {
const imagePath = args.image_path;
const format = args.format || "plain";
const prompts = {
plain: "Extract and transcribe all text from this image. Return only the text, nothing else.",
markdown: "Extract all text from this image and format it in markdown, preserving structure.",
structured: "Extract all text from this image and organize it with clear sections and structure."
};
const file = await uploadFile(imagePath);
const result = await model.generateContent([
prompts[format] || prompts.plain,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
const content = [prompt]
for (const imagePath of imagePaths) {
const file = await uploadFile(imagePath)
content.push({ fileData: { fileUri: file.uri, mimeType: file.mimeType } })
}
const result = await model.generateContent(content)
return result.response.text()
}
async function compareImages(args) {
const image1Path = args.image1_path;
const image2Path = args.image2_path;
const focus = args.focus || "differences";
const image1Path = args.image1_path
const image2Path = args.image2_path
const focus = args.focus || 'differences'
const prompts = {
differences: "Compare these two images and describe all the differences you can find.",
similarities: "Compare these two images and describe what they have in common.",
changes: "Describe what has changed between the first and second image."
};
changes: 'Describe what has changed between the first and second image.',
differences:
'Compare these two images and describe all the differences you can find.',
similarities:
'Compare these two images and describe what they have in common.',
}
const [file1, file2] = await Promise.all([
uploadFile(image1Path),
uploadFile(image2Path)
]);
uploadFile(image2Path),
])
const result = await model.generateContent([
prompts[focus] || prompts.differences,
{ fileData: { fileUri: file1.uri, mimeType: file1.mimeType }},
{ fileData: { fileUri: file2.uri, mimeType: file2.mimeType }}
]);
return result.response.text();
{ fileData: { fileUri: file1.uri, mimeType: file1.mimeType } },
{ fileData: { fileUri: file2.uri, mimeType: file2.mimeType } },
])
return result.response.text()
}
async function extractText(args) {
const imagePath = args.image_path
const format = args.format || 'plain'
const prompts = {
markdown:
'Extract all text from this image and format it in markdown, preserving structure.',
plain:
'Extract and transcribe all text from this image. Return only the text, nothing else.',
structured:
'Extract all text from this image and organize it with clear sections and structure.',
}
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompts[format] || prompts.plain,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
return result.response.text()
}
async function suggestFilename(args) {
const imagePath = args.image_path;
const maxLength = args.max_length || 60;
const includeDate = args.include_date || false;
const imagePath = args.image_path
const maxLength = args.max_length || 60
const includeDate = args.include_date || false
const prompt = `Analyze this image and suggest a descriptive filename for it.
Requirements:
- Maximum ${maxLength} characters (not including extension)
@@ -213,218 +251,257 @@ async function suggestFilename(args) {
- For screenshots: include the application or website name
- For diagrams: include the type and subject
- For photos: include the subject and context
- Return ONLY the filename suggestion, no explanation or extension`;
const file = await uploadFile(imagePath);
- Return ONLY the filename suggestion, no explanation or extension`
const file = await uploadFile(imagePath)
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
{ fileData: { fileUri: file.uri, mimeType: file.mimeType } },
])
// Clean up the suggestion and format it
let suggestion = result.response.text().trim();
let suggestion = result.response.text().trim()
// Remove any file extension if accidentally included
suggestion = suggestion.replace(/\.(png|jpg|jpeg|gif|webp|pdf)$/i, '');
suggestion = suggestion.replace(/\.(png|jpg|jpeg|gif|webp|pdf)$/i, '')
// Replace spaces with hyphens
suggestion = suggestion.replace(/\s+/g, ' ').replace(/ /g, ' - ');
suggestion = suggestion.replace(/\s+/g, ' ').replace(/ /g, ' - ')
// Ensure it doesn't exceed max length
if (suggestion.length > maxLength) {
suggestion = suggestion.substring(0, maxLength).replace(/ - $/, '');
suggestion = suggestion.substring(0, maxLength).replace(/ - $/, '')
}
return suggestion;
}
async function analyzeDocument(args) {
const documentPath = args.document_path;
const prompt = args.prompt || "Analyze this document and provide a comprehensive summary";
const file = await uploadFile(documentPath);
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
return suggestion
}
// Analyze video files or YouTube URLs
async function analyzeVideo(args) {
const videoPath = args.video_path;
const youtubeUrl = args.youtube_url;
const prompt = args.prompt || "Summarize this video in detail, including key moments and any text or speech content";
const videoPath = args.video_path
const youtubeUrl = args.youtube_url
const prompt =
args.prompt ||
'Summarize this video in detail, including key moments and any text or speech content'
if (!videoPath && !youtubeUrl) {
throw new Error("Either video_path or youtube_url is required");
throw new Error('Either video_path or youtube_url is required')
}
if (videoPath && youtubeUrl) {
throw new Error("Please provide either video_path or youtube_url, not both");
throw new Error('Please provide either video_path or youtube_url, not both')
}
let fileData;
let fileData
if (youtubeUrl) {
// YouTube URLs can be passed directly to the API
fileData = { fileUri: youtubeUrl };
fileData = { fileUri: youtubeUrl }
} else {
// Upload local video file
const file = await uploadFile(videoPath);
fileData = { fileUri: file.uri, mimeType: file.mimeType };
const file = await uploadFile(videoPath)
fileData = { fileUri: file.uri, mimeType: file.mimeType }
}
const result = await model.generateContent([
prompt,
{ fileData }
]);
const result = await model.generateContent([prompt, { fileData }])
return result.response.text();
return result.response.text()
}
// Create MCP server
const server = new Server(
{ name: "gemini-vision", version: "1.0.0" },
{ capabilities: { tools: {} }}
);
{ name: 'gemini-vision', version: '1.0.0' },
{ capabilities: { tools: {} } },
)
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "analyze_image",
description: "Analyze an image - transcribe text, describe content, or answer questions",
description:
'Analyze an image - transcribe text, describe content, or answer questions',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
prompt: { type: "string", description: "What to do with the image", default: "Describe this image" }
image_path: { description: 'Path to the image file', type: 'string' },
prompt: {
default: 'Describe this image',
description: 'What to do with the image',
type: 'string',
},
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'analyze_image',
},
{
name: "analyze_multiple",
description: "Analyze multiple images at once",
description: 'Analyze multiple images at once',
inputSchema: {
type: "object",
properties: {
image_paths: { type: "array", items: { type: "string" }, description: "List of image paths" },
prompt: { type: "string", description: "What to do with the images", default: "Analyze these images" }
image_paths: {
description: 'List of image paths',
items: { type: 'string' },
type: 'array',
},
prompt: {
default: 'Analyze these images',
description: 'What to do with the images',
type: 'string',
},
},
required: ["image_paths"]
}
required: ['image_paths'],
type: 'object',
},
name: 'analyze_multiple',
},
{
name: "extract_text",
description: "Extract and transcribe all text from an image (OCR)",
description: 'Extract and transcribe all text from an image (OCR)',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
format: { type: "string", enum: ["plain", "markdown", "structured"], default: "plain" }
format: {
default: 'plain',
enum: ['plain', 'markdown', 'structured'],
type: 'string',
},
image_path: { description: 'Path to the image file', type: 'string' },
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'extract_text',
},
{
name: "compare_images",
description: "Compare two images and describe differences or similarities",
description:
'Compare two images and describe differences or similarities',
inputSchema: {
type: "object",
properties: {
image1_path: { type: "string", description: "Path to first image" },
image2_path: { type: "string", description: "Path to second image" },
focus: { type: "string", enum: ["differences", "similarities", "changes"], default: "differences" }
focus: {
default: 'differences',
enum: ['differences', 'similarities', 'changes'],
type: 'string',
},
image1_path: { description: 'Path to first image', type: 'string' },
image2_path: { description: 'Path to second image', type: 'string' },
},
required: ["image1_path", "image2_path"]
}
required: ['image1_path', 'image2_path'],
type: 'object',
},
name: 'compare_images',
},
{
name: "suggest_image_filename",
description: "Analyze an image and suggest a descriptive filename (without extension)",
description:
'Analyze an image and suggest a descriptive filename (without extension)',
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
max_length: { type: "number", description: "Maximum filename length", default: 60 },
include_date: { type: "boolean", description: "Include date prefix in suggestion", default: false }
image_path: { description: 'Path to the image file', type: 'string' },
include_date: {
default: false,
description: 'Include date prefix in suggestion',
type: 'boolean',
},
max_length: {
default: 60,
description: 'Maximum filename length',
type: 'number',
},
},
required: ["image_path"]
}
required: ['image_path'],
type: 'object',
},
name: 'suggest_image_filename',
},
{
name: "analyze_video",
description: "Analyze video files or YouTube URLs - extract content, summarize, transcribe speech, identify objects/text. Provide either video_path OR youtube_url",
description:
'Analyze video files or YouTube URLs - extract content, summarize, transcribe speech, identify objects/text. Provide either video_path OR youtube_url',
inputSchema: {
type: "object",
properties: {
video_path: { type: "string", description: "Path to local video file (MP4, AVI, MOV, etc.)" },
youtube_url: { type: "string", description: "YouTube video URL (e.g., https://www.youtube.com/watch?v=...)" },
prompt: { type: "string", description: "What to analyze in the video", default: "Summarize this video in detail" }
prompt: {
default: 'Summarize this video in detail',
description: 'What to analyze in the video',
type: 'string',
},
video_path: {
description: 'Path to local video file (MP4, AVI, MOV, etc.)',
type: 'string',
},
youtube_url: {
description:
'YouTube video URL (e.g., https://www.youtube.com/watch?v=...)',
type: 'string',
},
},
required: []
}
required: [],
type: 'object',
},
name: 'analyze_video',
},
{
name: "analyze_document",
description: "Analyze a PDF or document with custom prompts - extract specific information, find mentions of topics, summarize sections, etc.",
description:
'Analyze a PDF or document with custom prompts - extract specific information, find mentions of topics, summarize sections, etc.',
inputSchema: {
type: "object",
properties: {
document_path: { type: "string", description: "Path to the document file (PDF, DOC, DOCX, ODT, RTF, TXT)" },
prompt: { type: "string", description: "What to analyze or extract from the document", default: "Analyze this document and provide a comprehensive summary" }
document_path: {
description:
'Path to the document file (PDF, DOC, DOCX, ODT, RTF, TXT)',
type: 'string',
},
prompt: {
default:
'Analyze this document and provide a comprehensive summary',
description: 'What to analyze or extract from the document',
type: 'string',
},
},
required: ["document_path"]
}
}
]
}));
required: ['document_path'],
type: 'object',
},
name: 'analyze_document',
},
],
}))
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const { arguments: args, name } = request.params
try {
let result;
let result
switch (name) {
case "analyze_image":
result = await analyzeImage(args);
break;
case "analyze_multiple":
result = await analyzeMultiple(args);
break;
case "extract_text":
result = await extractText(args);
break;
case "compare_images":
result = await compareImages(args);
break;
case "suggest_image_filename":
result = await suggestFilename(args);
break;
case "analyze_document":
result = await analyzeDocument(args);
break;
case "analyze_video":
result = await analyzeVideo(args);
break;
case 'analyze_document':
result = await analyzeDocument(args)
break
case 'analyze_image':
result = await analyzeImage(args)
break
case 'analyze_multiple':
result = await analyzeMultiple(args)
break
case 'analyze_video':
result = await analyzeVideo(args)
break
case 'compare_images':
result = await compareImages(args)
break
case 'extract_text':
result = await extractText(args)
break
case 'suggest_image_filename':
result = await suggestFilename(args)
break
default:
throw new Error(`Unknown tool: ${name}`);
throw new Error(`Unknown tool: ${name}`)
}
return {
content: [{ type: "text", text: result }]
};
content: [{ text: result, type: 'text' }],
}
} catch (error) {
throw new Error(`Tool execution failed: ${error.message}`);
throw new Error(`Tool execution failed: ${error.message}`)
}
});
})
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("🚀 Gemini Vision MCP Server running");
const transport = new StdioServerTransport()
await server.connect(transport)
console.error('🚀 Gemini Vision MCP Server running')
}
main().catch(console.error);
main().catch(console.error)
+1 -1
View File
@@ -15,4 +15,4 @@
}
]
}
}
}
+29 -13
View File
@@ -15,7 +15,23 @@ const autofix = process.env.CI ? 'error' : 'warn'
export default [
// Global ignore
{
ignores: ['**/*.json'],
ignores: [
'**/*.json',
'00_Inbox/**',
'01_Projects/**',
'02_Areas/**',
'03_Resources/**',
'04_Archives/**',
'05_Attachments/**',
'06_Metadata/**',
'OLD_VAULT/**',
'.obsidian/**',
'.trash/**',
'.tmp/**',
'.backup/**',
'node_modules/**',
'package-lock.json',
],
name: 'claudesidian/global-ignore',
},
@@ -100,17 +116,17 @@ export default [
'@typescript-eslint/prefer-literal-enum-member': ['error'],
'@typescript-eslint/prefer-namespace-keyword': [autofix],
'@typescript-eslint/triple-slash-reference': ['error'],
'check-file/filename-naming-convention': [
'error',
{ '**/*': 'KEBAB_CASE' },
{ ignoreMiddleExtensions: true },
],
'check-file/folder-naming-convention': [
'error',
{ '**/*': 'NEXT_JS_APP_ROUTER_CASE' },
{ ignoreMiddleExtensions: true },
],
'check-file/no-index': ['error', { ignoreMiddleExtensions: true }],
// File naming conventions - removed for flexibility
// 'check-file/filename-naming-convention': [
// 'error',
// { '**/*': 'KEBAB_CASE' },
// { ignoreMiddleExtensions: true },
// ],
// 'check-file/folder-naming-convention': [
// 'error',
// { '**/*': 'KEBAB_CASE' },
// { ignoreMiddleExtensions: true },
// ],
'constructor-super': ['error'],
'curly': [autofix, 'multi-line', 'consistent'],
'eqeqeq': [autofix, 'always', { null: 'ignore' }],
@@ -119,7 +135,7 @@ export default [
'import/enforce-node-protocol-usage': [autofix, 'always'],
'import/first': [autofix],
'import/newline-after-import': [autofix],
'import/no-default-export': ['error'],
// 'import/no-default-export': ['error'], // Disabled - config files need default exports
'import/no-duplicates': [autofix],
'import/no-mutable-exports': ['error'],
'logical-assignment-operators': [autofix],
-29
View File
@@ -1,29 +0,0 @@
# Ignore Obsidian folders
00_Inbox/
01_Projects/
02_Areas/
03_Resources/
04_Archives/
05_Attachments/
06_Metadata/
OLD_VAULT/
# Ignore dependencies
node_modules/
package-lock.json
# Ignore build/dist
dist/
build/
# Ignore hidden folders
.obsidian/
.trash/
.tmp/
.backup/
# Ignore git
.git/
# Ignore config folder
.config/
+1 -1
View File
@@ -26,4 +26,4 @@ changelog:
- maintenance
- title: Other Changes
labels:
- "*"
- '*'
+5 -6
View File
@@ -22,11 +22,11 @@ jobs:
)
runs-on: ubuntu-latest
permissions:
contents: write # Allow Claude to push changes
pull-requests: write # Allow Claude to create/modify PRs
issues: write # Allow Claude to create/update issues
contents: write # Allow Claude to push changes
pull-requests: write # Allow Claude to create/modify PRs
issues: write # Allow Claude to create/update issues
id-token: write
actions: read # Required for Claude to read CI results on PRs
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -38,7 +38,7 @@ jobs:
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
@@ -51,4 +51,3 @@ jobs:
# or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
claude_args: |
--allowed-tools "Bash(pnpm install),Bash(pnpm setup),Bash(pnpm attachments:*),Bash(pnpm vault:stats),Bash(pnpm check-updates),Bash(npm run *),Bash(git status),Bash(git diff *),Bash(git log *),Bash(git add *),Bash(git commit *),Bash(git push),Bash(gh pr *),Bash(gh issue *),Bash(ls *),Bash(cat *),Bash(grep *),Bash(find *),View,GlobTool,GrepTool,BatchTool,Read,Write,Edit"
+26 -13
View File
@@ -5,22 +5,29 @@ Helper scripts for vault automation and web content capture.
## Available Scripts
### Attachment Management
These are primarily called via npm/pnpm commands in package.json:
- `update-attachment-links.js` - Updates note links after moving attachments
- `fix-renamed-links.js` - Fixes links after renaming files
### Web Content Capture
**Note**: These scripts require API keys to function:
#### firecrawl-scrape.sh
Scrapes a single URL and saves as markdown.
```bash
# Requires FIRECRAWL_API_KEY environment variable
.scripts/firecrawl-scrape.sh <url> <output_file>
```
#### firecrawl-batch.sh
Scrapes multiple URLs and auto-generates filenames.
```bash
# Requires FIRECRAWL_API_KEY environment variable
.scripts/firecrawl-batch.sh <url1> <url2> <url3>
@@ -28,8 +35,11 @@ Scrapes multiple URLs and auto-generates filenames.
```
### Transcript Extraction
#### transcript-extract.sh
Extracts transcripts from YouTube videos.
```bash
.scripts/transcript-extract.sh <youtube-url>
```
@@ -38,21 +48,22 @@ Extracts transcripts from YouTube videos.
Run these from the vault root with `pnpm`:
| Command | Description |
|---------|-------------|
| `attachments:list` | Show first 20 unprocessed attachments |
| `attachments:count` | Count unprocessed attachments |
| `attachments:organized` | Count files in Organized folder |
| `attachments:unprocessed` | Same as count |
| `attachments:refs <file>` | Find references to a specific file |
| `attachments:sizes` | Show 20 largest attachment files |
| `attachments:orphans` | Find unreferenced attachments |
| `attachments:recent` | Show files added in last 7 days |
| `attachments:create-organized` | Create the Organized subfolder |
| Command | Description |
| ------------------------------ | ------------------------------------- |
| `attachments:list` | Show first 20 unprocessed attachments |
| `attachments:count` | Count unprocessed attachments |
| `attachments:organized` | Count files in Organized folder |
| `attachments:unprocessed` | Same as count |
| `attachments:refs <file>` | Find references to a specific file |
| `attachments:sizes` | Show 20 largest attachment files |
| `attachments:orphans` | Find unreferenced attachments |
| `attachments:recent` | Show files added in last 7 days |
| `attachments:create-organized` | Create the Organized subfolder |
## Setup Requirements
### For Web Scraping
1. Get a Firecrawl API key from [firecrawl.dev](https://firecrawl.dev)
2. Add to your shell profile:
```bash
@@ -60,11 +71,13 @@ Run these from the vault root with `pnpm`:
```
### For Transcript Extraction
- Requires `yt-dlp` and `jq` installed:
```bash
# macOS
brew install yt-dlp jq
# Linux
apt-get install yt-dlp jq
```
@@ -81,4 +94,4 @@ Run these from the vault root with `pnpm`:
- Scripts assume Unix-like environment (macOS/Linux)
- Windows users may need WSL or Git Bash
- All paths are relative to vault root
- Check script comments for additional requirements
- Check script comments for additional requirements
+68 -58
View File
@@ -3,85 +3,95 @@
/**
* Fixes attachment links after files have been renamed
* Usage: node .scripts/fix-renamed-links.js <old-name> <new-name>
*
*
* This properly handles the case where files are renamed, not just moved
*/
import fs from 'fs';
import path from 'path';
import fs from 'node:fs'
import path from 'node:path'
const args = process.argv.slice(2);
const args = process.argv.slice(2)
if (args.length !== 2) {
console.log('Usage: node .scripts/fix-renamed-links.js <old-filename> <new-filename>');
console.log('Example: node .scripts/fix-renamed-links.js "CleanShot 2025-01-01.png" "Project Screenshot.png"');
process.exit(1);
console.log(
'Usage: node .scripts/fix-renamed-links.js <old-filename> <new-filename>',
)
console.log(
'Example: node .scripts/fix-renamed-links.js "CleanShot 2025-01-01.png" "Project Screenshot.png"',
)
process.exit(1)
}
const [oldName, newName] = args;
const newPath = `05 Attachments/Organized/${newName}`;
const [oldName, newName] = args
const newPath = `05 Attachments/Organized/${newName}`
console.log(`Fixing links: ${oldName}${newName}`);
console.log(`Fixing links: ${oldName}${newName}`)
// Function to walk directory
function walkDir(dir, callback) {
fs.readdirSync(dir).forEach(f => {
const dirPath = path.join(dir, f);
const isDirectory = fs.statSync(dirPath).isDirectory();
if (isDirectory) {
// Skip node_modules, .git
if (!f.includes('node_modules') && !f.includes('.git')) {
walkDir(dirPath, callback);
}
} else {
callback(path.join(dir, f));
}
});
fs.readdirSync(dir).forEach((f) => {
const dirPath = path.join(dir, f)
const isDirectory = fs.statSync(dirPath).isDirectory()
if (isDirectory) {
// Skip node_modules, .git
if (!f.includes('node_modules') && !f.includes('.git')) {
walkDir(dirPath, callback)
}
} else {
callback(path.join(dir, f))
}
})
}
// Process all markdown files
let updatedCount = 0;
const updatedFiles = [];
let updatedCount = 0
const updatedFiles = []
walkDir('.', (filepath) => {
if (filepath.endsWith('.md')) {
let content = fs.readFileSync(filepath, 'utf8');
const originalContent = content;
// Escape special regex characters in filename
const escapedOld = oldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Pattern 1: ![[oldname]] without path
const pattern1 = new RegExp(`!\\[\\[${escapedOld}\\]\\]`, 'g');
content = content.replace(pattern1, `![[${newPath}]]`);
// Pattern 2: ![[05 Attachments/oldname]]
const pattern2 = new RegExp(`!\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
content = content.replace(pattern2, `![[${newPath}]]`);
// Pattern 3: [[oldname]] without ! (for PDFs and other non-embedded)
const pattern3 = new RegExp(`(?<!!)\\[\\[${escapedOld}\\]\\]`, 'g');
content = content.replace(pattern3, `[[${newPath}]]`);
// Pattern 4: [[05 Attachments/oldname]] without !
const pattern4 = new RegExp(`(?<!!)\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
content = content.replace(pattern4, `[[${newPath}]]`);
// Write back if changed
if (content !== originalContent) {
fs.writeFileSync(filepath, content, 'utf8');
updatedFiles.push(filepath);
updatedCount++;
}
if (filepath.endsWith('.md')) {
let content = fs.readFileSync(filepath, 'utf8')
const originalContent = content
// Escape special regex characters in filename
const escapedOld = oldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
// Pattern 1: ![[oldname]] without path
const pattern1 = new RegExp(`!\\[\\[${escapedOld}\\]\\]`, 'g')
content = content.replace(pattern1, `![[${newPath}]]`)
// Pattern 2: ![[05 Attachments/oldname]]
const pattern2 = new RegExp(
`!\\[\\[05 Attachments/${escapedOld}\\]\\]`,
'g',
)
content = content.replace(pattern2, `![[${newPath}]]`)
// Pattern 3: [[oldname]] without ! (for PDFs and other non-embedded)
const pattern3 = new RegExp(`(?<!!)\\[\\[${escapedOld}\\]\\]`, 'g')
content = content.replace(pattern3, `[[${newPath}]]`)
// Pattern 4: [[05 Attachments/oldname]] without !
const pattern4 = new RegExp(
`(?<!!)\\[\\[05 Attachments/${escapedOld}\\]\\]`,
'g',
)
content = content.replace(pattern4, `[[${newPath}]]`)
// Write back if changed
if (content !== originalContent) {
fs.writeFileSync(filepath, content, 'utf8')
updatedFiles.push(filepath)
updatedCount++
}
});
}
})
// Report results
if (updatedCount > 0) {
console.log(`\nUpdated ${updatedCount} files:`);
updatedFiles.forEach(file => console.log(` - ${file}`));
console.log(`\nUpdated ${updatedCount} files:`)
updatedFiles.forEach((file) => console.log(` - ${file}`))
} else {
console.log('\nNo files needed updating');
console.log('\nNo files needed updating')
}
console.log('\nDone!');
console.log('\nDone!')
+98 -75
View File
@@ -3,104 +3,127 @@
/**
* Updates attachment links in markdown files after files are moved to Organized folder
* Usage: node .scripts/update-attachment-links.js [specific-file.ext]
*
*
* If no argument provided, updates all files in Organized folder
* If specific filename provided, only updates references to that file
*/
import fs from 'fs';
import path from 'path';
import fs from 'node:fs'
import path from 'node:path'
const organizedDir = '05 Attachments/Organized';
const args = process.argv.slice(2);
const specificFile = args[0];
const organizedDir = '05 Attachments/Organized'
const args = process.argv.slice(2)
const specificFile = args[0]
// Get list of files to update references for
let filesToUpdate = [];
let filesToUpdate = []
if (specificFile) {
// Update references for a specific file
filesToUpdate = [specificFile];
console.log(`Updating references for: ${specificFile}`);
// Update references for a specific file
filesToUpdate = [specificFile]
console.log(`Updating references for: ${specificFile}`)
} else if (fs.existsSync(organizedDir)) {
// Update references for all files in Organized folder
filesToUpdate = fs.readdirSync(organizedDir)
console.log(`Found ${filesToUpdate.length} files in Organized folder`)
} else {
// Update references for all files in Organized folder
if (fs.existsSync(organizedDir)) {
filesToUpdate = fs.readdirSync(organizedDir);
console.log(`Found ${filesToUpdate.length} files in Organized folder`);
} else {
console.log('Organized folder does not exist yet');
process.exit(0);
}
console.log('Organized folder does not exist yet')
process.exit(0)
}
// Function to walk directory
function walkDir(dir, callback) {
fs.readdirSync(dir).forEach(f => {
const dirPath = path.join(dir, f);
const isDirectory = fs.statSync(dirPath).isDirectory();
if (isDirectory) {
// Skip node_modules, .git, and the Organized folder itself
if (!f.includes('node_modules') && !f.includes('.git') && dirPath !== organizedDir) {
walkDir(dirPath, callback);
}
} else {
callback(path.join(dir, f));
}
});
fs.readdirSync(dir).forEach((f) => {
const dirPath = path.join(dir, f)
const isDirectory = fs.statSync(dirPath).isDirectory()
if (isDirectory) {
// Skip node_modules, .git, and the Organized folder itself
if (
!f.includes('node_modules') &&
!f.includes('.git') &&
dirPath !== organizedDir
) {
walkDir(dirPath, callback)
}
} else {
callback(path.join(dir, f))
}
})
}
// Process all markdown files
let updatedCount = 0;
const updatedFiles = [];
let updatedCount = 0
const updatedFiles = []
walkDir('.', (filepath) => {
if (filepath.endsWith('.md')) {
let content = fs.readFileSync(filepath, 'utf8');
const originalContent = content;
// For each file to update, fix references
filesToUpdate.forEach(filename => {
// Escape special regex characters in filename
const escapedFile = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Pattern 1: ![[filename]] without path
const pattern1 = new RegExp(`!\\[\\[${escapedFile}\\]\\]`, 'g');
content = content.replace(pattern1, `![[05 Attachments/Organized/${filename}]]`);
// Pattern 2: ![[05 Attachments/filename]] (file in root being moved)
const pattern2 = new RegExp(`!\\[\\[05 Attachments/${escapedFile}\\]\\]`, 'g');
content = content.replace(pattern2, `![[05 Attachments/Organized/${filename}]]`);
// Pattern 3: [[filename]] without ! (for PDFs and other non-embedded links)
// Only if not already pointing to Organized
const pattern3 = new RegExp(`\\[\\[${escapedFile}\\]\\]`, 'g');
const pattern3Organized = new RegExp(`\\[\\[05 Attachments/Organized/${escapedFile}\\]\\]`, 'g');
// Only replace if not already pointing to Organized and not preceded by !
if (!pattern3Organized.test(content)) {
content = content.replace(pattern3, `[[05 Attachments/Organized/${filename}]]`);
}
// Pattern 4: [[05 Attachments/filename]] without !
const pattern4 = new RegExp(`\\[\\[05 Attachments/${escapedFile}\\]\\]`, 'g');
content = content.replace(pattern4, `[[05 Attachments/Organized/${filename}]]`);
});
// Write back if changed
if (content !== originalContent) {
fs.writeFileSync(filepath, content, 'utf8');
updatedFiles.push(filepath);
updatedCount++;
}
if (filepath.endsWith('.md')) {
let content = fs.readFileSync(filepath, 'utf8')
const originalContent = content
// For each file to update, fix references
filesToUpdate.forEach((filename) => {
// Escape special regex characters in filename
const escapedFile = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
// Pattern 1: ![[filename]] without path
const pattern1 = new RegExp(`!\\[\\[${escapedFile}\\]\\]`, 'g')
content = content.replace(
pattern1,
`![[05 Attachments/Organized/${filename}]]`,
)
// Pattern 2: ![[05 Attachments/filename]] (file in root being moved)
const pattern2 = new RegExp(
`!\\[\\[05 Attachments/${escapedFile}\\]\\]`,
'g',
)
content = content.replace(
pattern2,
`![[05 Attachments/Organized/${filename}]]`,
)
// Pattern 3: [[filename]] without ! (for PDFs and other non-embedded links)
// Only if not already pointing to Organized
const pattern3 = new RegExp(`\\[\\[${escapedFile}\\]\\]`, 'g')
const pattern3Organized = new RegExp(
`\\[\\[05 Attachments/Organized/${escapedFile}\\]\\]`,
'g',
)
// Only replace if not already pointing to Organized and not preceded by !
if (!pattern3Organized.test(content)) {
content = content.replace(
pattern3,
`[[05 Attachments/Organized/${filename}]]`,
)
}
// Pattern 4: [[05 Attachments/filename]] without !
const pattern4 = new RegExp(
`\\[\\[05 Attachments/${escapedFile}\\]\\]`,
'g',
)
content = content.replace(
pattern4,
`[[05 Attachments/Organized/${filename}]]`,
)
})
// Write back if changed
if (content !== originalContent) {
fs.writeFileSync(filepath, content, 'utf8')
updatedFiles.push(filepath)
updatedCount++
}
});
}
})
// Report results
if (updatedCount > 0) {
console.log(`\nUpdated ${updatedCount} files:`);
updatedFiles.forEach(file => console.log(` - ${file}`));
console.log(`\nUpdated ${updatedCount} files:`)
updatedFiles.forEach((file) => console.log(` - ${file}`))
} else {
console.log('\nNo files needed updating');
console.log('\nNo files needed updating')
}
console.log('\nDone!');
console.log('\nDone!')
+27 -3
View File
@@ -5,6 +5,7 @@ Inactive items preserved for future reference.
## Purpose
The Archive stores:
- Completed projects with their outputs
- Inactive areas no longer maintained
- Old notes for historical reference
@@ -14,21 +15,25 @@ The Archive stores:
## What Goes Here
### From Projects
- Completed projects with final deliverables
- Cancelled projects with lessons learned
- Projects inactive for 30+ days
### From Areas
- Areas no longer relevant to your life
- Responsibilities you've handed off
- Roles you no longer have
### From Resources
- Outdated information (but historically interesting)
- Superseded frameworks or methods
- Old versions of evolved ideas
### From Inbox
- Processed items no longer needed
- Old daily notes (after extraction)
- Random captures without lasting value
@@ -48,6 +53,7 @@ The Archive stores:
## Archival Process
### Before Archiving Projects
1. Create completion summary
2. Extract reusable insights to Resources
3. Document lessons learned
@@ -55,33 +61,38 @@ The Archive stores:
5. Move entire folder with structure intact
### Sample Completion Summary
```markdown
# Project: [Name] - Completion Summary
**Duration**: Start date - End date
**Status**: Completed/Cancelled/Suspended
**Duration**: Start date - End date **Status**: Completed/Cancelled/Suspended
## Objectives
- Original goal 1 ✓
- Original goal 2 ✓
- Original goal 3 ✗
## Key Outcomes
- What was delivered
- What impact it had
- What value was created
## Lessons Learned
- What worked well
- What didn't work
- What to do differently
## Reusable Assets
- Templates created: [[link]]
- Processes developed: [[link]]
- Insights gained: [[link]]
## Related Notes
- Continues in: [[Area name]]
- See also: [[Related project]]
```
@@ -89,6 +100,7 @@ The Archive stores:
## Claude Code Workflows
### Archive Project
```
Help me archive [project name].
Create a completion summary.
@@ -97,12 +109,14 @@ Move everything to Archive.
```
### Search Archive
```
Search the archive for anything about [topic].
I need historical context.
```
### Year in Review
```
Review all archived projects from [year].
What patterns do you see?
@@ -110,6 +124,7 @@ What did I accomplish?
```
### Resurrect Project
```
I want to revive [archived project].
What was the status when archived?
@@ -119,12 +134,14 @@ What would need updating?
## Archive Philosophy
### It's Not a Graveyard
- Archives preserve institutional memory
- Old projects inform new ones
- Patterns emerge over time
- Ideas can be resurrected
### It's Not a Dumping Ground
- Archive thoughtfully
- Maintain some organization
- Keep summaries accessible
@@ -133,6 +150,7 @@ What would need updating?
## Claude Code Prompts
### Historical Analysis
```
Look at my archived projects.
What types of things do I tend to start but not finish?
@@ -140,12 +158,14 @@ What themes recur?
```
### Knowledge Mining
```
Search the archive for any mentions of [concept].
How has my thinking evolved?
```
### Pattern Recognition
```
Analyze my project completion rate.
What factors correlate with success?
@@ -155,11 +175,13 @@ What patterns predict failure?
## Maintenance
### Quarterly
- Review recent additions
- Ensure summaries exist
- Check for resurrection candidates
### Annually
- Major archive cleanup
- Delete what's truly dead
- Extract any missed insights
@@ -175,4 +197,6 @@ What patterns predict failure?
## Remember
The Archive is your institutional memory. It's not about holding onto everything, but about preserving what might inform future work. Use Claude Code to help you see patterns across time and extract wisdom from experience.
The Archive is your institutional memory. It's not about holding onto
everything, but about preserving what might inform future work. Use Claude Code
to help you see patterns across time and extract wisdom from experience.
+67 -15
View File
@@ -3,19 +3,23 @@
All notable changes to claudesidian will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.10.1] - 2025-01-15
### Fixed
- Corrected GitHub Action configuration to use claude_args instead of allowed_tools
- Corrected GitHub Action configuration to use claude_args instead of
allowed_tools
- Fixed workflow validation error for allowed tools parameter
## [0.10.0] - 2025-01-15
### Added
- GitHub Actions workflow for Claude Code integration
- Claude can now respond to @claude mentions in issues and PRs
- Configured permissions for Claude to create PRs and push changes
@@ -28,39 +32,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.9.2] - 2025-01-14
### Fixed
- Corrected Firecrawl script examples to use `npm run` commands
- Added contributing guideline about reviewing AI-generated content before submission
- Added contributing guideline about reviewing AI-generated content before
submission
### Removed
- Removed Common Patterns section from README (redundant)
## [0.9.1] - 2025-01-14
### Changed
- Enhanced Gemini Vision documentation to explain direct image/PDF processing benefits
- Enhanced Firecrawl documentation to explain full-text capture and context preservation
- Enhanced Gemini Vision documentation to explain direct image/PDF processing
benefits
- Enhanced Firecrawl documentation to explain full-text capture and context
preservation
- Added detailed API key setup instructions for both Gemini and Firecrawl
### Removed
- Removed Essential Workflows section from README (redundant with command descriptions)
- Removed Essential Workflows section from README (redundant with command
descriptions)
## [0.9.0] - 2025-01-14
### Added
- Enhanced upgrade command documentation with detailed usage examples and safety features
- Enhanced upgrade command documentation with detailed usage examples and safety
features
- Contributing section with guidelines for community contributions
- MIT license file for clear open-source licensing
### Changed
- Improved documentation clarity on Claude Code commands vs agents distinction
- Updated contributing guidelines to encourage PRs for commands, agents, and core updates
- Updated contributing guidelines to encourage PRs for commands, agents, and
core updates
### Removed
- Removed thinking-partner agent (keeping slash command only)
## [0.8.8] - 2025-01-13
### Fixed
- Added critical warnings to upgrade command documentation
- Emphasized requirement to show diffs before applying changes
- Added correct vs wrong implementation examples
@@ -69,6 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.7] - 2025-01-13
### Fixed
- Release command now automatically creates GitHub release using gh CLI
- Prevents missing GitHub releases (like v0.8.2-v0.8.5 were)
- Extracts release notes from CHANGELOG.md for GitHub release body
@@ -76,11 +95,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.6] - 2025-01-13
### Changed
- Improved semantic versioning guidelines in release command with clearer decision guide
- Improved semantic versioning guidelines in release command with clearer
decision guide
## [0.8.5] - 2025-01-13
### Fixed
- Upgrade command now works without git connection for disconnected users
- Clone latest version to .tmp/ directory instead of requiring upstream remote
- Use .tmp/ instead of /tmp/ to hide upgrade files from Obsidian
@@ -91,6 +113,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.4] - 2025-01-13
### Fixed
- Simplified upgrade command to systematically check all system files
- Created upgrade checklist to track progress file-by-file
- Filtered upgrades to only claudesidian system files, not user content
@@ -100,6 +123,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.3] - 2025-01-13
### Fixed
- Improved init-bootstrap vault selection for multiple vaults
- Added explicit confirmation before importing any vault
- Enhanced user identification prompts with better explanations
@@ -109,6 +133,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.2] - 2025-01-13
### Fixed
- Improved SessionStart hook formatting with arrow indicators for commands
- Fixed update notification display to show clean output instead of raw JSON
- Enhanced visual layout of first-run and update messages
@@ -116,6 +141,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.1] - 2025-01-13
### Changed
- Updated README with comprehensive feature descriptions including:
- Smart vault analysis and pattern detection capabilities
- User research and profile building features
@@ -126,19 +152,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.8.0] - 2025-01-13
### Added
- Automatic update check on session start
- SessionStart hook that fetches latest version from GitHub and compares to local
- SessionStart hook that fetches latest version from GitHub and compares to
local
- Update notifications when newer versions are available
- check-updates npm script for version comparison
- Works even after disconnecting from original repository
### Changed
- Enhanced release command documentation with clearer semantic versioning guidelines
- Enhanced release command documentation with clearer semantic versioning
guidelines
- Better guidance on when to use feat: vs fix: vs refactor: in commits
## [0.7.0] - 2025-01-13
### Added
- Comprehensive vault analysis using tree, note sampling, and pattern detection
- Enhanced profile building with URL fetching and custom context
- Dynamic date generation for timestamps in CLAUDE.md
@@ -147,6 +178,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Deeper research capabilities with disambiguation confirmation
### Changed
- init-bootstrap now analyzes vault structure before importing
- Always confirms user identity even with single search result
- Waits to create folders until after organization method selection
@@ -155,6 +187,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Profile building includes comprehensive background from provided URLs
### Fixed
- Correct file counting without depth limits
- Proper ordering of import before personalization questions
- More accurate detection of user preferences from existing vault
@@ -162,6 +195,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.6.0] - 2025-01-13
### Added
- Intelligent vault import that preserves existing structure in OLD_VAULT folder
- Auto-detection of existing Obsidian vaults by searching for .obsidian folders
- User research and disambiguation for personalized setup
@@ -173,6 +207,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Clear examples for folder naming when cloning repository
### Changed
- init-bootstrap now imports entire vault structure safely without data loss
- Gemini Vision and Firecrawl prompts clarify tools are already included
- README includes examples of custom folder names when cloning
@@ -181,18 +216,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.5.0] - 2025-01-13
### Added
- First-run welcome message using SessionStart hook
- FIRST_RUN marker file to detect fresh installations
- Markdown-formatted welcome prompt with setup instructions
- Automatic detection and guidance for new users
### Changed
- init-bootstrap now removes FIRST_RUN marker after setup completion
- Hook configuration uses inline commands (no external scripts needed)
## [0.4.0] - 2025-01-13
### Added
- Simplified setup process with enhanced init-bootstrap command:
- Automatic disconnection from original repository
- Folder rename assistance for non-git users
@@ -201,12 +239,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Multiple setup paths in README for different user skill levels
### Changed
- init-bootstrap now handles complete environment setup including git management
- README updated with clearer Quick Start instructions for both technical and non-technical users
- README updated with clearer Quick Start instructions for both technical and
non-technical users
## [0.3.1] - 2025-01-13
### Fixed
- Removed CLAUDE.md and settings.local.json from repository tracking
- These user-specific files are now generated locally by init-bootstrap
- Added both files to .gitignore to prevent accidental commits
@@ -215,8 +256,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.3.0] - 2025-01-13
### Added
- Intelligent upgrade command (`/upgrade`) with AI-powered semantic merging
- Smart conflict resolution that preserves user customizations while adding new features
- Smart conflict resolution that preserves user customizations while adding new
features
- Automatic backup system with rollback capabilities
- Selective update categories (AI-mergeable, auto-safe, protected)
- Based on 2025 best practices for LLM-powered code migration
@@ -224,11 +267,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.3] - 2025-01-13
### Changed
- Updated init-bootstrap command and settings configuration
## [0.2.2] - 2025-01-13
### Fixed
- Corrected all documentation to use proper slash command syntax (/command-name)
- Fixed examples showing incorrect 'claude run' syntax
- Updated README, CLAUDE.md, install.sh, and command docs
@@ -236,6 +281,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.1] - 2025-01-13
### Changed
- Updated README to use init-bootstrap command instead of install.sh
- Simplified Quick Start instructions to 2-step process
- Added examples of pre-configured commands in README
@@ -243,6 +289,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.0] - 2025-01-13
### Added
- Release command for automated version management and releases
- Gemini Vision video analysis support:
- Local video files (MP4, AVI, MOV, WebM, MKV, WMV, FLV, 3GP, M4V)
@@ -251,12 +298,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated documentation with video analysis examples
### Changed
- Enhanced init-bootstrap command with full environment setup including MCP configuration
- Enhanced init-bootstrap command with full environment setup including MCP
configuration
- Updated Gemini Vision MCP server to support video formats
## [0.1.0] - 2025-01-13
### Added
- Initial release of claudesidian - Claude Code + Obsidian starter kit
- PARA method folder structure (00_Inbox through 06_Metadata)
- Bootstrap initialization system via `claude run init-bootstrap`
@@ -286,9 +336,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Git integration with proper .gitignore
### Changed
- Replaced static CLAUDE.md with dynamic init-bootstrap command
### Security
- API keys stored in environment variables
- .mcp.json gitignored for security
@@ -317,4 +369,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[0.2.2]: https://github.com/heyitsnoah/claudesidian/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/heyitsnoah/claudesidian/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/heyitsnoah/claudesidian/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/heyitsnoah/claudesidian/releases/tag/v0.1.0
[0.1.0]: https://github.com/heyitsnoah/claudesidian/releases/tag/v0.1.0
+32 -2
View File
@@ -10,9 +10,12 @@
## Version Control Best Practices
**CRITICAL - START EVERY SESSION**: Always run `git pull` at the beginning of each new Claude session to ensure you have the latest changes from the remote repository.
**CRITICAL - START EVERY SESSION**: Always run `git pull` at the beginning of
each new Claude session to ensure you have the latest changes from the remote
repository.
**Commit workflow**:
- After creating new notes: `git add .``git commit -m "message"``git push`
- After significant edits: Commit and push immediately
- Use `git status` to check for modifications
@@ -38,21 +41,25 @@ vault/
## PARA Method Details
### Projects (01)
- Time-bound initiatives with clear completion criteria
- Examples: Writing a paper, developing a presentation
- Recommended subfolders: Research/, Drafts/, References/, Output/
### Areas (02)
- Ongoing responsibilities without end dates
- Examples: Health, Finances, Professional Development
- Create dedicated notes with links to related resources
### Resources (03)
- Topics of interest for reference
- Knowledge bases organized by subject
- Use for information not tied to specific projects
### Archive (04)
- Completed or inactive items
- Maintain same folder structure as active sections
- Review periodically for reactivation
@@ -60,16 +67,19 @@ vault/
## Inbox Management
### Core Principles
- Inbox is temporary, not permanent storage
- Process weekly using Capture → Process → Organize workflow
- Maintain <20 items at any time
### Files to Keep in Inbox
- **CRITICAL**: Files with number prefixes (00-06) stay permanently
- Recent daily/weekly summaries (last 3 months)
- Active notes being processed
### Processing Workflow
1. Delete obsolete information
2. Move relevant material to PARA locations
3. Convert actions into project tasks
@@ -78,12 +88,14 @@ vault/
## File Organization Guidelines
### Naming Conventions
- Daily notes: `YYYY-MM-DD - Topic`
- Meeting notes: `Meeting - [Topic] - YYYY-MM-DD`
- Ideas: `Idea - [Brief Description]`
- Resources: `Resource - [Topic] - [Source]`
### Movement Rules
- Use `mv` command (not `cp`) to avoid duplicates
- Verify destination folders exist first
- Update internal links after moves
@@ -92,11 +104,13 @@ vault/
## Attachments Management
### Organization
- Store all non-text files in `05_Attachments/`
- Processed files → `05_Attachments/Organized/`
- Naming: `[RelatedNote]_[Description].[ext]`
### Helper Scripts
```bash
pnpm attachments:list # List unprocessed files
pnpm attachments:organized # Count organized files
@@ -107,11 +121,13 @@ pnpm attachments:update-links # Update links after moving
## Web Content Workflow
### Built-in Tools (Preferred)
- **WebSearch**: For general web searches
- **WebFetch**: For specific URLs
- Save to appropriate folder based on content type
### Custom Scripts (When Needed)
- Single URL: `pnpm firecrawl:scrape <url> <output>`
- Batch URLs: `pnpm firecrawl:batch <url1> <url2>`
- Saves to `00_Inbox/Clippings/` with frontmatter
@@ -119,12 +135,14 @@ pnpm attachments:update-links # Update links after moving
## Writing Style Guidelines
### Structure
- Use `[[WikiLinks]]` for internal references
- Include YAML frontmatter (dates, tags, status)
- Consistent Markdown formatting
- Specific, consistent tags
### Style Preferences
- Direct and confident statements
- Avoid clichéd transitions
- Let statements stand on their own
@@ -133,17 +151,20 @@ pnpm attachments:update-links # Update links after moving
## AI Assistant Guidelines
### Before Any Organization
1. Map complete folder structure: `find . -type d | sort`
2. Document in `06_Metadata/STRUCTURE.md`
3. Verify all destination folders exist
### Working with Content
- Respect numbered core files (never move 00-06 prefixed files)
- Always use `mv` not `cp` when organizing
- Preserve and update bidirectional links
- Add appropriate YAML frontmatter
### Simple Commands Only
- **REQUIRED**: Direct, basic commands without filtering
- **FORBIDDEN**: Complex regex, piped commands, find with filters
- Example RIGHT: `ls -1` then manually select files
@@ -152,16 +173,19 @@ pnpm attachments:update-links # Update links after moving
## Daily Workflows
### Start of Day
1. Run `git pull`
2. Check inbox for items to process
3. Review active projects
### End of Day
1. Process new inbox items
2. Commit and push changes
3. Update project notes
### Weekly Review
1. Process entire inbox
2. Archive completed projects
3. Update area notes
@@ -170,16 +194,19 @@ pnpm attachments:update-links # Update links after moving
## Project Lifecycle
### Starting a Project
1. Create folder in `01_Projects/[ProjectName]`
2. Add subfolders: Research/, Drafts/, Output/
3. Create README with objectives and timeline
### During Project
- Keep all related materials in project folder
- Link to relevant resources and areas
- Regular commits to track progress
### Completing a Project
1. Create project summary note
2. Move entire folder to `04_Archive/`
3. Update relevant area notes
@@ -188,18 +215,21 @@ pnpm attachments:update-links # Update links after moving
## Best Practices
### Organization
- Keep folder structure shallow (max 3 levels)
- Create subfolders only with 7+ related notes
- Use linking over deep nesting
- Include README in major folders
### Content Creation
- Capture first, organize later
- One idea per note
- Link generously
- Tag consistently
### Maintenance
- Weekly inbox processing
- Monthly project reviews
- Quarterly archive cleanup
@@ -207,4 +237,4 @@ pnpm attachments:update-links # Update links after moving
---
*This is a bootstrap template. Customize based on your workflow and needs.*
_This is a bootstrap template. Customize based on your workflow and needs._
+12 -4
View File
@@ -1,6 +1,7 @@
# Contributing to Claudesidian
Thank you for your interest in contributing to claudesidian! This document provides guidelines for contributing to the project.
Thank you for your interest in contributing to claudesidian! This document
provides guidelines for contributing to the project.
## Development Setup
@@ -11,7 +12,8 @@ Thank you for your interest in contributing to claudesidian! This document provi
## Commit Message Convention
We follow [Conventional Commits](https://www.conventionalcommits.org/) for clear commit history:
We follow [Conventional Commits](https://www.conventionalcommits.org/) for clear
commit history:
- `feat:` New feature
- `fix:` Bug fix
@@ -22,6 +24,7 @@ We follow [Conventional Commits](https://www.conventionalcommits.org/) for clear
- `chore:` Maintenance tasks
Examples:
```
feat: add new research-assistant command
fix: correct attachment link updates in scripts
@@ -31,6 +34,7 @@ docs: update README with MCP setup instructions
## Versioning
We use [Semantic Versioning](https://semver.org/):
- MAJOR (1.0.0): Breaking changes
- MINOR (0.1.0): New features (backward compatible)
- PATCH (0.0.1): Bug fixes (backward compatible)
@@ -44,19 +48,23 @@ We use [Semantic Versioning](https://semver.org/):
## Changelog Updates
When contributing, add your changes to CHANGELOG.md under the "Unreleased" section:
When contributing, add your changes to CHANGELOG.md under the "Unreleased"
section:
```markdown
## [Unreleased]
### Added
- Your new feature here
### Fixed
- Your bug fix here
```
Use these categories:
- **Added** - New features
- **Changed** - Changes to existing functionality
- **Deprecated** - Features to be removed
@@ -82,4 +90,4 @@ Use these categories:
## Questions?
Feel free to open an issue for discussion before making large changes.
Feel free to open an issue for discussion before making large changes.
+67 -16
View File
@@ -4,7 +4,9 @@ Turn your Obsidian vault into an AI-powered second brain using Claude Code.
## What is this?
This is a pre-configured Obsidian vault structure designed to work seamlessly with Claude Code, enabling you to:
This is a pre-configured Obsidian vault structure designed to work seamlessly
with Claude Code, enabling you to:
- Use AI as a thinking partner, not just a writing assistant
- Organize knowledge using the PARA method
- Maintain version control with Git
@@ -15,6 +17,7 @@ This is a pre-configured Obsidian vault structure designed to work seamlessly wi
### 1. Get the Starter Kit
**Option A: Clone with Git**
```bash
# Clone with your preferred folder name (replace 'my-vault' with any name you like)
git clone https://github.com/heyitsnoah/claudesidian.git my-vault
@@ -27,11 +30,13 @@ cd my-vault
```
**Option B: Download ZIP (no Git required)**
1. Click "Code" → "Download ZIP" on GitHub
2. Extract to your desired location
3. Open the folder in Claude Code
### 2. Run the Setup Wizard
```bash
# Start Claude Code in the directory
claude
@@ -41,6 +46,7 @@ claude
```
This will:
- Install dependencies automatically
- Disconnect from the original claudesidian repository
- **Intelligently analyze** your existing vault structure and patterns
@@ -54,12 +60,15 @@ This will:
- Initialize Git for version control
### 3. Open in Obsidian (Optional but Recommended)
- Download [Obsidian](https://obsidian.md)
- Open vault from the claudesidian folder
- This gives you a visual interface alongside Claude Code
### 4. Your First Session
Tell Claude Code:
```
I'm starting a new project about [topic].
I'm in thinking mode, not writing mode.
@@ -68,6 +77,7 @@ then help me explore this topic by asking questions.
```
Or use one of the pre-configured commands (in Claude Code):
```
/thinking-partner # For collaborative exploration
/daily-review # For end-of-day reflection
@@ -95,12 +105,14 @@ claudesidian/
### Thinking Mode vs Writing Mode
**Thinking Mode** (Research & Exploration):
- Claude asks questions to understand your goals
- Searches existing notes for relevant content
- Helps make connections between ideas
- Maintains a log of insights and progress
**Writing Mode** (Content Creation):
- Generates drafts based on your research
- Helps structure and edit content
- Creates final deliverables
@@ -108,18 +120,22 @@ claudesidian/
### The PARA Method
**Projects**: Have a deadline and specific outcome
- Example: "Q4 2025 Marketing Strategy"
- Create a folder in `01_Projects/`
**Areas**: Ongoing without an end date
- Example: "Health", "Finances", "Team Management"
- Lives in `02_Areas/`
**Resources**: Topics of ongoing interest
- Example: "AI Research", "Writing Tips"
- Store in `03_Resources/`
**Archive**: Inactive items
- Completed projects with their outputs
- Old notes no longer relevant
@@ -141,9 +157,11 @@ Run with: `/[command-name]` in Claude Code
### Staying Updated with `/upgrade`
Claudesidian automatically checks for updates when you start Claude Code and will remind you to run `/upgrade` when new features are available.
Claudesidian automatically checks for updates when you start Claude Code and
will remind you to run `/upgrade` when new features are available.
The upgrade command intelligently merges new features while preserving your customizations:
The upgrade command intelligently merges new features while preserving your
customizations:
```bash
# Preview what would be updated (recommended first)
@@ -157,6 +175,7 @@ The upgrade command intelligently merges new features while preserving your cust
```
**What the upgrade does:**
- Creates a timestamped backup before making any changes
- Shows you diffs for each file before updating
- Preserves your personal notes and customizations
@@ -165,6 +184,7 @@ The upgrade command intelligently merges new features while preserving your cust
- Provides rollback capability if needed
**Safety features:**
- All your personal content is protected
- Complete backup created in `.backup/upgrade-[timestamp]/`
- File-by-file review and confirmation
@@ -173,16 +193,21 @@ The upgrade command intelligently merges new features while preserving your cust
## Vision & Document Analysis (Optional)
With [Google Gemini](https://ai.google.dev/) MCP configured, Claude Code can process your attachments directly without having to describe them. This means:
With [Google Gemini](https://ai.google.dev/) MCP configured, Claude Code can
process your attachments directly without having to describe them. This means:
- **Direct image analysis**: Claude sees the actual image, not your description
- **PDF text extraction**: Full document text without copy-pasting
- **Bulk processing**: Analyze multiple screenshots or documents at once
- **Smart organization**: Auto-generate filenames based on image content
- **Comparison tasks**: Compare before/after screenshots, designs, etc.
**Why this matters**: Instead of describing "a screenshot showing an error message", Claude Code directly sees and reads the error. Perfect for debugging UI issues, analyzing charts, or processing scanned documents.
**Why this matters**: Instead of describing "a screenshot showing an error
message", Claude Code directly sees and reads the error. Perfect for debugging
UI issues, analyzing charts, or processing scanned documents.
**Getting a Gemini API key:**
1. Visit [Google AI Studio](https://aistudio.google.com)
2. Sign in with your Google account
3. Click "Get API key" in the left sidebar
@@ -193,16 +218,23 @@ See `.claude/mcp-servers/README.md` for full setup instructions
## Web Research (Optional)
With [Firecrawl](https://www.firecrawl.dev/) configured, our helper scripts fetch and save full web content directly to your vault. This means:
- **Full text capture**: Scripts pipe complete article text to files, not summaries
With [Firecrawl](https://www.firecrawl.dev/) configured, our helper scripts
fetch and save full web content directly to your vault. This means:
- **Full text capture**: Scripts pipe complete article text to files, not
summaries
- **Context preservation**: Claude doesn't need to hold web content in memory
- **Batch processing**: Save multiple articles at once with `firecrawl-batch.sh`
- **Clean markdown**: Web pages converted to readable, searchable markdown
- **Permanent archive**: Your research stays in your vault forever
**Why this matters**: Instead of Claude reading a webpage and summarizing it (losing detail), the scripts save the FULL text. Claude can then search and analyze thousands of saved articles without hitting context limits. Perfect for research projects, documentation archives, or building a knowledge base.
**Why this matters**: Instead of Claude reading a webpage and summarizing it
(losing detail), the scripts save the FULL text. Claude can then search and
analyze thousands of saved articles without hitting context limits. Perfect for
research projects, documentation archives, or building a knowledge base.
**Example workflow:**
```bash
# Save a single article
npm run firecrawl:scrape -- "https://example.com/article" "03_Resources/Articles"
@@ -212,6 +244,7 @@ npm run firecrawl:batch -- urls.txt "03_Resources/Research"
```
**Getting a Firecrawl API key:**
1. Visit [Firecrawl](https://www.firecrawl.dev) and sign up
2. Get 300 free credits to start (open-source, can self-host)
3. Go to your dashboard to find your API key
@@ -233,6 +266,7 @@ Run these with `pnpm`:
### Git Integration
Initialize Git for version control:
```bash
git init
git add .
@@ -242,6 +276,7 @@ git push -u origin main
```
Best practices:
- Commit after each work session
- Use descriptive commit messages
- Pull before starting work
@@ -259,8 +294,10 @@ Best practices:
Create specialized commands by saving instructions in `.claude/commands/`:
**Research Assistant** (`06_Metadata/Agents/research-assistant.md`):
```markdown
You are a research assistant.
- Search the vault for relevant information
- Synthesize findings from multiple sources
- Identify gaps in knowledge
@@ -280,16 +317,19 @@ You are a research assistant.
## Troubleshooting
### Claude Code can't find my notes
- Make sure you're running Claude Code from the vault root directory
- Check file permissions
- Verify markdown files have `.md` extension
### Git conflicts
- Always pull before starting work
- Commit frequently with clear messages
- Use branches for experimental changes
### Attachment management
- Run `npm run attachments:create-organized` to set up folders
- Use helper scripts to find orphaned files
- Keep attachments under 10MB for Git
@@ -306,7 +346,8 @@ This setup is based on key principles:
## Contributing
We welcome contributions from the community! This is a living template that gets better with everyone's input.
We welcome contributions from the community! This is a living template that gets
better with everyone's input.
### How to Contribute
@@ -327,7 +368,8 @@ We welcome contributions from the community! This is a living template that gets
- **Workflow templates**: Share your productive workflows
- **Helper scripts**: Automation tools that make vault management easier
- **Integration guides**: Connect Claudesidian with other tools
- **Core updates**: Improvements to the upgrade system, setup wizard, or other core features
- **Core updates**: Improvements to the upgrade system, setup wizard, or other
core features
### Guidelines
@@ -336,16 +378,20 @@ We welcome contributions from the community! This is a living template that gets
- Test thoroughly before submitting
- Follow existing code style and structure
- Update the CHANGELOG.md with your changes
- **AI-generated content is welcome, but you MUST carefully read and review everything before submitting** - never submit code you don't understand
- **AI-generated content is welcome, but you MUST carefully read and review
everything before submitting** - never submit code you don't understand
### Getting Updates
When new features are contributed and merged, users can easily get them with:
```bash
/upgrade
```
The upgrade command intelligently merges new features while preserving your personal customizations, making it easy to benefit from community contributions without losing your work.
The upgrade command intelligently merges new features while preserving your
personal customizations, making it easy to benefit from community contributions
without losing your work.
### Questions or Ideas?
@@ -353,7 +399,8 @@ The upgrade command intelligently merges new features while preserving your pers
- Join discussions in existing issues
- Share your use cases - they help us understand needs better
Remember: best practices emerge from use, not theory. Your real-world experience makes this better for everyone!
Remember: best practices emerge from use, not theory. Your real-world experience
makes this better for everyone!
## Resources
@@ -364,8 +411,12 @@ Remember: best practices emerge from use, not theory. Your real-world experience
## Inspiration
This starter kit was inspired by the workflows discussed in:
- [How to Use Claude Code as a Second Brain](https://every.to/podcast/how-to-use-claude-code-as-a-thinking-partner) - Noah Brier's interview with Dan Shipper
- Built by the team at [Alephic](https://alephic.com) - an AI-first strategy and software partner that helps organizations solve complex challenges through custom AI systems
- [How to Use Claude Code as a Second Brain](https://every.to/podcast/how-to-use-claude-code-as-a-thinking-partner) -
Noah Brier's interview with Dan Shipper
- Built by the team at [Alephic](https://alephic.com) - an AI-first strategy and
software partner that helps organizations solve complex challenges through
custom AI systems
## License
@@ -373,4 +424,4 @@ MIT - Use this however you want. Make it your own.
---
*Remember: The bicycle feels wobbly at first, then you forget it was ever hard.*
_Remember: The bicycle feels wobbly at first, then you forget it was ever hard._