From 48135c045faba85dcfaf6e72f88aeeb27c857939 Mon Sep 17 00:00:00 2001 From: Noah Brier Date: Sun, 14 Sep 2025 15:03:10 -0400 Subject: [PATCH 1/3] feat: add download-attachment and pull-request commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add /download-attachment command for downloading files from URLs - Add /pull-request command for creating PRs in one step - Expose transcript:extract script in package.json šŸ¤– Generated with Claude Code Co-Authored-By: Claude --- .claude/commands/download-attachment.md | 100 +++++++++++++++ .claude/commands/pull-request.md | 157 ++++++++++++++++++++++++ package.json | 1 + 3 files changed, 258 insertions(+) create mode 100644 .claude/commands/download-attachment.md create mode 100644 .claude/commands/pull-request.md diff --git a/.claude/commands/download-attachment.md b/.claude/commands/download-attachment.md new file mode 100644 index 0000000..dce60b7 --- /dev/null +++ b/.claude/commands/download-attachment.md @@ -0,0 +1,100 @@ +# download-attachment + +Download files from URLs to attachments folder and organize them with descriptive names. + +## Usage +``` +/download-attachment [url2] [url3...] +``` + +## Examples +``` +/download-attachment https://example.com/document.pdf +/download-attachment https://site.com/image.png https://site.com/report.pdf +``` + +## Implementation + +You are tasked with downloading files from URLs and organizing them in the Obsidian vault attachments folder. + +### Step 1: Parse URLs +Extract the URL(s) from the user's input. Handle multiple URLs if provided. + +### Step 2: Download Files +For each URL: +```bash +# Create temp filename based on URL +# Use wget or curl to download +wget -O "05_Attachments/[filename]" "[url]" +# or +curl -L "[url]" -o "05_Attachments/[filename]" +``` + +### Step 3: Verify Downloads +Check that files were downloaded successfully: +```bash +ls -la "05_Attachments/" +``` + +### Step 4: Organize Files +After downloading, run the organize-attachments command to rename files with descriptive names: + +For PDFs: +- Extract text with `pdftotext` +- Analyze content for meaningful title + +For Images: +- Use `mcp__gemini-vision__analyze_image` or `mcp__gemini-vision__analyze_multiple` +- Generate descriptive filename based on content + +### Step 5: Move to Organized +Move renamed files to `05_Attachments/Organized/` with descriptive names + +### Step 6: Update Index +Add entries to `05_Attachments/00_Index.md` + +### Step 7: Commit Changes +```bash +git add -A +git commit -m "Download and organize attachments from URLs" +git push +``` + +## Important Notes + +1. **File Naming**: + - Initial download: Use URL filename or generate from URL + - After analysis: Rename with descriptive title + +2. **Supported Types**: + - Images: .png, .jpg, .jpeg, .gif, .webp + - Documents: .pdf, .doc, .docx + - Text: .txt, .md + - Data: .csv, .xlsx + +3. **Error Handling**: + - Check if URL is accessible + - Verify file downloaded correctly + - Handle download failures gracefully + +4. **Organization**: + - Downloaded files go to `05_Attachments/` + - After renaming, move to `05_Attachments/Organized/` + - Update links across vault if needed + +## Workflow + +1. Download file(s) from provided URL(s) +2. Identify file type and analyze content +3. Generate descriptive filename +4. Move to Organized folder +5. Update index and references +6. Commit and push changes + +## Tips + +- For multiple URLs, process them in batch for efficiency +- Use Gemini Vision for batch image analysis (up to 3 at once) +- Extract meaningful context from PDFs before renaming +- Preserve original file extensions +- Keep filenames concise but descriptive (max 60 chars) \ No newline at end of file diff --git a/.claude/commands/pull-request.md b/.claude/commands/pull-request.md new file mode 100644 index 0000000..e96918c --- /dev/null +++ b/.claude/commands/pull-request.md @@ -0,0 +1,157 @@ +# Pull Request Command + +Creates a new feature branch, commits changes, pushes to GitHub, and opens a pull request - all in one command. Perfect for contributing features or fixes. + +## Task + +Automate the entire pull request workflow: create branch, stage changes, commit with descriptive message, push to GitHub, and open PR with proper description. + +## Process + +### 1. **Check Prerequisites** + - Ensure git repository exists + - Check for uncommitted changes to include + - Verify GitHub CLI (`gh`) is available + - Get current branch as base branch + +### 2. **Create Feature Branch** + ```bash + # Generate branch name from PR title or use provided name + # Format: feature/short-description or fix/issue-name + git checkout -b feature/[branch-name] + ``` + +### 3. **Stage and Review Changes** + - Show `git status` to user + - Show `git diff --staged` for review + - If no staged changes, stage all changes: `git add -A` + - Confirm changes with user before proceeding + +### 4. **Commit Changes** + - Analyze changes to create meaningful commit message + - Use conventional commits format (feat:, fix:, docs:, etc.) + - Include detailed commit body if changes are complex + ```bash + git commit -m "feat: add new feature + + - Detail 1 + - Detail 2 + + šŸ¤– Generated with Claude Code" + ``` + +### 5. **Push to GitHub** + ```bash + # Push with upstream tracking + git push -u origin feature/[branch-name] + ``` + +### 6. **Create Pull Request** + Use `gh pr create` with: + - Descriptive title + - Detailed body with: + - Summary of changes + - Testing checklist + - Related issues (if any) + - Set base branch (usually main/master) + + ```bash + gh pr create \ + --title "Feature: Add awesome new capability" \ + --body "$(cat <<'EOF' + ## Summary + Brief description of what this PR does + + ## Changes + - Added feature X + - Fixed bug Y + - Improved performance of Z + + ## Testing + - [ ] Tested locally + - [ ] All tests pass + - [ ] Documentation updated + + ## Screenshots + (if applicable) + + šŸ¤– Generated with [Claude Code](https://claude.ai/code) + EOF + )" \ + --base main + ``` + +### 7. **Provide Next Steps** + - Show PR URL + - Remind about review process + - Suggest next actions (request review, add labels, etc.) + +## Arguments + +- **Optional**: Branch name (auto-generated from changes if not provided) +- **Optional**: PR title (analyzed from changes if not provided) +- **Optional**: Target branch (defaults to main/master) + +## Example Usage + +```bash +# Auto-generate branch and PR from changes +/pull-request + +# Specify branch name +/pull-request feature/add-auth + +# Full specification +/pull-request fix/bug-123 "Fix: Resolve authentication timeout issue" develop +``` + +## Output Example + +``` +šŸ“ Analyzing changes... +🌿 Creating branch: feature/add-download-command +āœ… Committed: feat: add download-attachment command +šŸ“¤ Pushed to origin +šŸ”— Pull Request created: https://github.com/user/repo/pull/42 + +Next steps: +- Request review from team members +- Add relevant labels +- Link related issues +``` + +## Branch Naming Conventions + +- **Features**: `feature/description` +- **Fixes**: `fix/issue-or-description` +- **Documentation**: `docs/what-updated` +- **Refactoring**: `refactor/what-changed` +- **Performance**: `perf/optimization` +- **Tests**: `test/what-tested` + +## Commit Message Format + +Follow conventional commits: +- `feat:` New feature +- `fix:` Bug fix +- `docs:` Documentation only +- `style:` Formatting, missing semicolons, etc. +- `refactor:` Code change that neither fixes a bug nor adds a feature +- `perf:` Performance improvement +- `test:` Adding missing tests +- `chore:` Changes to build process or auxiliary tools + +## Safety Features + +- Confirm before pushing if changes are large +- Show diff before committing +- Verify PR description before creating +- Check if PR already exists for branch +- Handle merge conflicts gracefully + +## Error Handling + +- If no changes: "No changes to create PR" +- If already on feature branch: Ask if should create PR from current branch +- If PR exists: Show existing PR URL +- If push fails: Check permissions and remote settings \ No newline at end of file diff --git a/package.json b/package.json index 1fc0297..0677162 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "attachments:orphans": "for file in 05_Attachments/*; do basename \"$file\" | xargs -I {} sh -c 'grep -r \"{}\" . --include=\"*.md\" > /dev/null || echo \"{}\"'; done", "attachments:recent": "find 05_Attachments -type f -mtime -7 -exec ls -la {} \\;", "attachments:create-organized": "mkdir -p 05_Attachments/Organized", + "transcript:extract": ".scripts/transcript-extract.sh", "vault:stats": ".scripts/vault-stats.sh", "check-updates": "REMOTE=$(curl -s https://raw.githubusercontent.com/heyitsnoah/claudesidian/main/package.json | grep version | head -1 | sed 's/.*: \"\\(.*\\)\".*/\\1/') && LOCAL=$(grep version package.json | head -1 | sed 's/.*: \"\\(.*\\)\".*/\\1/') && if [ \"$LOCAL\" != \"$REMOTE\" ]; then echo -e \"šŸ“¦ Update available! Latest: $REMOTE (you have: $LOCAL)\\n\\n⬇\\n/upgrade\\n⬆\\n\\n## What will this do\\n\\nāœ… Update to the latest version of Claudesidian\\nāœ… Get new features and improvements\\nāœ… Preserve your vault content and settings\\n\\n\"; fi" }, From 7b86627727d0b6741cc23904d6092e580a403b41 Mon Sep 17 00:00:00 2001 From: Noah Brier Date: Sun, 14 Sep 2025 17:15:52 -0400 Subject: [PATCH 2/3] fix: address security concerns from PR review - Add URL validation to download-attachment (only allow http/https) - Add filename sanitization to prevent path traversal attacks - Add timeouts to download commands (30 seconds) - Add branch name sanitization in pull-request command - Check for existing branches to avoid conflicts - Add check for current feature branch Addresses security concerns raised by Claude in PR #1 review --- .claude/commands/download-attachment.md | 22 +++++++++++++++++----- .claude/commands/pull-request.md | 12 +++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.claude/commands/download-attachment.md b/.claude/commands/download-attachment.md index dce60b7..cc60516 100644 --- a/.claude/commands/download-attachment.md +++ b/.claude/commands/download-attachment.md @@ -17,17 +17,29 @@ Download files from URLs to attachments folder and organize them with descriptiv You are tasked with downloading files from URLs and organizing them in the Obsidian vault attachments folder. -### Step 1: Parse URLs +### Step 1: Parse and Validate URLs Extract the URL(s) from the user's input. Handle multiple URLs if provided. +- **Validate URL scheme**: Only allow http:// or https:// URLs +- **Reject invalid URLs**: file://, ftp://, or malformed URLs +- **Example validation**: +```bash +if [[ ! "$url" =~ ^https?:// ]]; then + echo "Error: Only HTTP/HTTPS URLs are allowed" + exit 1 +fi +``` ### Step 2: Download Files For each URL: ```bash -# Create temp filename based on URL -# Use wget or curl to download -wget -O "05_Attachments/[filename]" "[url]" +# Sanitize filename to prevent path traversal +# Remove ../ and other dangerous characters +filename=$(basename "$url" | sed 's/[^a-zA-Z0-9._-]/_/g') + +# Use wget or curl to download with timeout +wget --timeout=30 -O "05_Attachments/$filename" "$url" # or -curl -L "[url]" -o "05_Attachments/[filename]" +curl --max-time 30 -L "$url" -o "05_Attachments/$filename" ``` ### Step 3: Verify Downloads diff --git a/.claude/commands/pull-request.md b/.claude/commands/pull-request.md index e96918c..0a79e7c 100644 --- a/.claude/commands/pull-request.md +++ b/.claude/commands/pull-request.md @@ -13,12 +13,22 @@ Automate the entire pull request workflow: create branch, stage changes, commit - Check for uncommitted changes to include - Verify GitHub CLI (`gh`) is available - Get current branch as base branch + - If already on feature branch, ask: "Create PR from current branch?" ### 2. **Create Feature Branch** ```bash # Generate branch name from PR title or use provided name + # Sanitize branch name: lowercase, replace spaces with hyphens, remove special chars + branch_name=$(echo "$branch_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g') + + # Check if branch already exists + if git show-ref --verify --quiet refs/heads/$branch_name; then + echo "Branch $branch_name already exists, using alternative name" + branch_name="${branch_name}-$(date +%s)" + fi + # Format: feature/short-description or fix/issue-name - git checkout -b feature/[branch-name] + git checkout -b $branch_name ``` ### 3. **Stage and Review Changes** From 8773dcff33814cb47b1dccaf88ab6b04b94d0f6f Mon Sep 17 00:00:00 2001 From: Noah Brier Date: Wed, 17 Sep 2025 16:06:52 -0400 Subject: [PATCH 3/3] fix: format files to pass lint checks --- .claude/commands/download-attachment.md | 31 ++++- .claude/commands/pull-request.md | 148 +++++++++++++----------- CHANGELOG.md | 3 +- 3 files changed, 107 insertions(+), 75 deletions(-) diff --git a/.claude/commands/download-attachment.md b/.claude/commands/download-attachment.md index cc60516..3b6ecd1 100644 --- a/.claude/commands/download-attachment.md +++ b/.claude/commands/download-attachment.md @@ -1,13 +1,16 @@ # download-attachment -Download files from URLs to attachments folder and organize them with descriptive names. +Download files from URLs to attachments folder and organize them with +descriptive names. ## Usage + ``` /download-attachment [url2] [url3...] ``` ## Examples + ``` /download-attachment https://example.com/document.pdf /download-attachment https://site.com/image.png https://site.com/report.pdf @@ -15,13 +18,17 @@ Download files from URLs to attachments folder and organize them with descriptiv ## Implementation -You are tasked with downloading files from URLs and organizing them in the Obsidian vault attachments folder. +You are tasked with downloading files from URLs and organizing them in the +Obsidian vault attachments folder. ### Step 1: Parse and Validate URLs + Extract the URL(s) from the user's input. Handle multiple URLs if provided. + - **Validate URL scheme**: Only allow http:// or https:// URLs - **Reject invalid URLs**: file://, ftp://, or malformed URLs - **Example validation**: + ```bash if [[ ! "$url" =~ ^https?:// ]]; then echo "Error: Only HTTP/HTTPS URLs are allowed" @@ -30,7 +37,9 @@ fi ``` ### Step 2: Download Files + For each URL: + ```bash # Sanitize filename to prevent path traversal # Remove ../ and other dangerous characters @@ -43,29 +52,39 @@ curl --max-time 30 -L "$url" -o "05_Attachments/$filename" ``` ### Step 3: Verify Downloads + Check that files were downloaded successfully: + ```bash ls -la "05_Attachments/" ``` ### Step 4: Organize Files -After downloading, run the organize-attachments command to rename files with descriptive names: + +After downloading, run the organize-attachments command to rename files with +descriptive names: For PDFs: + - Extract text with `pdftotext` - Analyze content for meaningful title For Images: -- Use `mcp__gemini-vision__analyze_image` or `mcp__gemini-vision__analyze_multiple` + +- Use `mcp__gemini-vision__analyze_image` or + `mcp__gemini-vision__analyze_multiple` - Generate descriptive filename based on content ### Step 5: Move to Organized + Move renamed files to `05_Attachments/Organized/` with descriptive names ### Step 6: Update Index + Add entries to `05_Attachments/00_Index.md` ### Step 7: Commit Changes + ```bash git add -A git commit -m "Download and organize attachments from URLs" @@ -74,7 +93,7 @@ git push ## Important Notes -1. **File Naming**: +1. **File Naming**: - Initial download: Use URL filename or generate from URL - After analysis: Rename with descriptive title @@ -109,4 +128,4 @@ git push - Use Gemini Vision for batch image analysis (up to 3 at once) - Extract meaningful context from PDFs before renaming - Preserve original file extensions -- Keep filenames concise but descriptive (max 60 chars) \ No newline at end of file +- Keep filenames concise but descriptive (max 60 chars) diff --git a/.claude/commands/pull-request.md b/.claude/commands/pull-request.md index 0a79e7c..ef526d4 100644 --- a/.claude/commands/pull-request.md +++ b/.claude/commands/pull-request.md @@ -1,100 +1,111 @@ # Pull Request Command -Creates a new feature branch, commits changes, pushes to GitHub, and opens a pull request - all in one command. Perfect for contributing features or fixes. +Creates a new feature branch, commits changes, pushes to GitHub, and opens a +pull request - all in one command. Perfect for contributing features or fixes. ## Task -Automate the entire pull request workflow: create branch, stage changes, commit with descriptive message, push to GitHub, and open PR with proper description. +Automate the entire pull request workflow: create branch, stage changes, commit +with descriptive message, push to GitHub, and open PR with proper description. ## Process ### 1. **Check Prerequisites** - - Ensure git repository exists - - Check for uncommitted changes to include - - Verify GitHub CLI (`gh`) is available - - Get current branch as base branch - - If already on feature branch, ask: "Create PR from current branch?" + +- Ensure git repository exists +- Check for uncommitted changes to include +- Verify GitHub CLI (`gh`) is available +- Get current branch as base branch +- If already on feature branch, ask: "Create PR from current branch?" ### 2. **Create Feature Branch** - ```bash - # Generate branch name from PR title or use provided name - # Sanitize branch name: lowercase, replace spaces with hyphens, remove special chars - branch_name=$(echo "$branch_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g') - # Check if branch already exists - if git show-ref --verify --quiet refs/heads/$branch_name; then - echo "Branch $branch_name already exists, using alternative name" - branch_name="${branch_name}-$(date +%s)" - fi +```bash +# Generate branch name from PR title or use provided name +# Sanitize branch name: lowercase, replace spaces with hyphens, remove special chars +branch_name=$(echo "$branch_name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g') - # Format: feature/short-description or fix/issue-name - git checkout -b $branch_name - ``` +# Check if branch already exists +if git show-ref --verify --quiet refs/heads/$branch_name; then + echo "Branch $branch_name already exists, using alternative name" + branch_name="${branch_name}-$(date +%s)" +fi + +# Format: feature/short-description or fix/issue-name +git checkout -b $branch_name +``` ### 3. **Stage and Review Changes** - - Show `git status` to user - - Show `git diff --staged` for review - - If no staged changes, stage all changes: `git add -A` - - Confirm changes with user before proceeding + +- Show `git status` to user +- Show `git diff --staged` for review +- If no staged changes, stage all changes: `git add -A` +- Confirm changes with user before proceeding ### 4. **Commit Changes** - - Analyze changes to create meaningful commit message - - Use conventional commits format (feat:, fix:, docs:, etc.) - - Include detailed commit body if changes are complex - ```bash - git commit -m "feat: add new feature - - Detail 1 - - Detail 2 +- Analyze changes to create meaningful commit message +- Use conventional commits format (feat:, fix:, docs:, etc.) +- Include detailed commit body if changes are complex - šŸ¤– Generated with Claude Code" - ``` +```bash +git commit -m "feat: add new feature + +- Detail 1 +- Detail 2 + +šŸ¤– Generated with Claude Code" +``` ### 5. **Push to GitHub** - ```bash - # Push with upstream tracking - git push -u origin feature/[branch-name] - ``` + +```bash +# Push with upstream tracking +git push -u origin feature/[branch-name] +``` ### 6. **Create Pull Request** - Use `gh pr create` with: - - Descriptive title - - Detailed body with: - - Summary of changes - - Testing checklist - - Related issues (if any) - - Set base branch (usually main/master) - ```bash - gh pr create \ - --title "Feature: Add awesome new capability" \ - --body "$(cat <<'EOF' - ## Summary - Brief description of what this PR does +Use `gh pr create` with: - ## Changes - - Added feature X - - Fixed bug Y - - Improved performance of Z +- Descriptive title +- Detailed body with: + - Summary of changes + - Testing checklist + - Related issues (if any) +- Set base branch (usually main/master) - ## Testing - - [ ] Tested locally - - [ ] All tests pass - - [ ] Documentation updated +```bash +gh pr create \ + --title "Feature: Add awesome new capability" \ + --body "$(cat <<'EOF' +## Summary +Brief description of what this PR does - ## Screenshots - (if applicable) +## Changes +- Added feature X +- Fixed bug Y +- Improved performance of Z - šŸ¤– Generated with [Claude Code](https://claude.ai/code) - EOF - )" \ - --base main - ``` +## Testing +- [ ] Tested locally +- [ ] All tests pass +- [ ] Documentation updated + +## Screenshots +(if applicable) + +šŸ¤– Generated with [Claude Code](https://claude.ai/code) +EOF +)" \ + --base main +``` ### 7. **Provide Next Steps** - - Show PR URL - - Remind about review process - - Suggest next actions (request review, add labels, etc.) + +- Show PR URL +- Remind about review process +- Suggest next actions (request review, add labels, etc.) ## Arguments @@ -142,6 +153,7 @@ Next steps: ## Commit Message Format Follow conventional commits: + - `feat:` New feature - `fix:` Bug fix - `docs:` Documentation only @@ -164,4 +176,4 @@ Follow conventional commits: - If no changes: "No changes to create PR" - If already on feature branch: Ask if should create PR from current branch - If PR exists: Show existing PR URL -- If push fails: Check permissions and remote settings \ No newline at end of file +- If push fails: Check permissions and remote settings diff --git a/CHANGELOG.md b/CHANGELOG.md index 11d17b5..6604d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ and this project adheres to ### Added - Comprehensive linting and formatting setup with ESLint and Prettier -- Configuration files organized in `.config/` folder for better project structure +- Configuration files organized in `.config/` folder for better project + structure - GitHub Action workflow for automated lint checks on pull requests - Package manager specification for consistent dependency management