From ac77be6eded420d19f74c18339100e076f1c8a14 Mon Sep 17 00:00:00 2001 From: dlond Date: Wed, 20 Aug 2025 20:16:35 +1200 Subject: [PATCH] Update CLAUDE.md and add GitHub automation workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restructure CLAUDE.md with project leadership and clearer organization - Add GitHub workflows for daily summaries and lead notifications - Add issue template for rebase reminders - Add hooks README for future git hook documentation Closes #17 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/ISSUE_TEMPLATE/rebase-reminder.md | 33 +++++ .github/hooks/README.md | 2 + .github/workflows/daily-summary.yml | 59 +++++++++ .github/workflows/lead-notifications.yml | 128 ++++++++++++++++++++ CLAUDE.md | 140 +++++++++++++++------- 5 files changed, 316 insertions(+), 46 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/rebase-reminder.md create mode 100644 .github/hooks/README.md create mode 100644 .github/workflows/daily-summary.yml create mode 100644 .github/workflows/lead-notifications.yml diff --git a/.github/ISSUE_TEMPLATE/rebase-reminder.md b/.github/ISSUE_TEMPLATE/rebase-reminder.md new file mode 100644 index 00000000..d5f99fde --- /dev/null +++ b/.github/ISSUE_TEMPLATE/rebase-reminder.md @@ -0,0 +1,33 @@ +--- +name: Rebase Reminder +about: Automated reminder to rebase active worktrees +title: '⚠️ Rebase Reminder: [PR NUMBER]' +labels: rebase-reminder, automated +assignees: '' +--- + +## Action Required +PR #[NUMBER] has been merged to main. Active worktrees should be rebased. + +## Steps to Rebase + +```bash +# Update main +cd ~/dev/projects/[PROJECT] +git fetch origin main +git pull origin main + +# For each active worktree +cd ~/dev/worktrees/[PROJECT]/[WORKTREE] +git rebase origin/main +git push --force-with-lease +``` + +## Checklist +- [ ] Main branch updated +- [ ] Active worktrees identified +- [ ] Each worktree rebased +- [ ] Changes pushed with --force-with-lease + +--- +*This is an automated reminder. Close this issue once all worktrees are rebased.* diff --git a/.github/hooks/README.md b/.github/hooks/README.md new file mode 100644 index 00000000..fbc96a84 --- /dev/null +++ b/.github/hooks/README.md @@ -0,0 +1,2 @@ +# GitHub Hooks +Place webhook processing scripts here diff --git a/.github/workflows/daily-summary.yml b/.github/workflows/daily-summary.yml new file mode 100644 index 00000000..1f5bf0a5 --- /dev/null +++ b/.github/workflows/daily-summary.yml @@ -0,0 +1,59 @@ +name: Daily Activity Summary + +on: + schedule: + - cron: '0 9 * * *' # 9 AM daily + workflow_dispatch: # Allow manual trigger + +jobs: + generate-summary: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: read + + steps: + - name: Generate Activity Summary + id: summary + run: | + echo "# 📊 Daily Activity Summary" > summary.md + echo "**Date**: $(date -u +"%Y-%m-%d")" >> summary.md + echo "**Repository**: ${{ github.repository }}" >> summary.md + echo "" >> summary.md + + # Get open PRs + echo "## 🔄 Open Pull Requests" >> summary.md + gh pr list --repo ${{ github.repository }} --state open --limit 10 --json number,title,author,createdAt \ + --jq '.[] | "- PR #\(.number): \(.title) by @\(.author.login)"' >> summary.md || echo "- None" >> summary.md + echo "" >> summary.md + + # Get open issues + echo "## 📝 Open Issues" >> summary.md + gh issue list --repo ${{ github.repository }} --state open --limit 10 --json number,title,author,createdAt \ + --jq '.[] | "- Issue #\(.number): \(.title) by @\(.author.login)"' >> summary.md || echo "- None" >> summary.md + echo "" >> summary.md + + # Recent merges (last 24 hours) + echo "## ✅ Recently Merged (24h)" >> summary.md + gh pr list --repo ${{ github.repository }} --state merged --limit 5 --json number,title,mergedAt \ + --jq '.[] | select(.mergedAt > (now - 86400 | strftime("%Y-%m-%dT%H:%M:%SZ"))) | "- PR #\(.number): \(.title)"' >> summary.md || echo "- None" >> summary.md + + cat summary.md + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Summary Issue + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + run: | + # Close previous daily summaries + gh issue list --repo ${{ github.repository }} --label "daily-summary" --state open --json number \ + --jq '.[].number' | xargs -I {} gh issue close {} --repo ${{ github.repository }} || true + + # Create new summary + gh issue create \ + --repo ${{ github.repository }} \ + --title "📊 Daily Summary: $(date -u +"%Y-%m-%d")" \ + --body-file summary.md \ + --label "daily-summary,automated" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lead-notifications.yml b/.github/workflows/lead-notifications.yml new file mode 100644 index 00000000..eb404873 --- /dev/null +++ b/.github/workflows/lead-notifications.yml @@ -0,0 +1,128 @@ +name: Lead Notifications + +on: + issues: + types: [opened, closed, reopened, assigned, unassigned] + pull_request: + types: [opened, closed, reopened, review_requested, ready_for_review, merged] + pull_request_review: + types: [submitted] + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + push: + branches: [main] + +jobs: + notify-lead: + runs-on: ubuntu-latest + if: github.actor != 'github-actions[bot]' # Don't notify about bot actions + + steps: + - name: Generate Summary + id: summary + run: | + # Determine event description + case "${{ github.event_name }}" in + "issues") + DESCRIPTION="Issue #${{ github.event.issue.number }}: ${{ github.event.action }}" + URL="${{ github.event.issue.html_url }}" + ;; + "pull_request") + DESCRIPTION="PR #${{ github.event.pull_request.number }}: ${{ github.event.action }}" + URL="${{ github.event.pull_request.html_url }}" + ;; + "pull_request_review") + DESCRIPTION="Review on PR #${{ github.event.pull_request.number }}" + URL="${{ github.event.review.html_url }}" + ;; + "issue_comment") + DESCRIPTION="Comment on #${{ github.event.issue.number }}" + URL="${{ github.event.comment.html_url }}" + ;; + "pull_request_review_comment") + DESCRIPTION="Review comment on PR #${{ github.event.pull_request.number }}" + URL="${{ github.event.comment.html_url }}" + ;; + "push") + DESCRIPTION="Push to main by ${{ github.actor }}" + URL="${{ github.event.compare }}" + ;; + *) + DESCRIPTION="${{ github.event_name }} by ${{ github.actor }}" + URL="${{ github.server_url }}/${{ github.repository }}" + ;; + esac + + echo "description=$DESCRIPTION" >> $GITHUB_OUTPUT + echo "url=$URL" >> $GITHUB_OUTPUT + + - name: Create Desktop Notification (macOS) + if: runner.os == 'macOS' + run: | + osascript -e 'display notification "${{ steps.summary.outputs.description }}" with title "[${{ github.repository }}]" sound name "Glass"' + + - name: Log Activity + run: | + echo "📢 Repository Activity:" + echo "Repository: ${{ github.repository }}" + echo "Event: ${{ github.event_name }}" + echo "Actor: ${{ github.actor }}" + echo "Description: ${{ steps.summary.outputs.description }}" + echo "URL: ${{ steps.summary.outputs.url }}" + echo "Time: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" + + # Optional: Post to Slack + # - name: Slack Notification + # if: github.event_name == 'pull_request' && github.event.action == 'opened' + # uses: slackapi/slack-github-action@v1 + # with: + # payload: | + # { + # "text": "New PR in ${{ github.repository }}", + # "blocks": [{ + # "type": "section", + # "text": { + # "type": "mrkdwn", + # "text": "🔔 *${{ steps.summary.outputs.description }}*\n<${{ steps.summary.outputs.url }}|View on GitHub>" + # } + # }] + # } + # env: + # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + rebase-reminder: + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true + + steps: + - name: Create Rebase Reminder Issue + run: | + gh issue create \ + --repo ${{ github.repository }} \ + --title "⚠️ Rebase Reminder: PR #${{ github.event.pull_request.number }} merged" \ + --body "PR #${{ github.event.pull_request.number }} was merged to main. + +Active worktrees should be rebased to avoid conflicts: + +\`\`\`bash +# Update main +cd ~/dev/projects/$(basename ${{ github.repository }}) +git fetch origin main +git pull origin main + +# For each active worktree +cd ~/dev/worktrees/$(basename ${{ github.repository }})/ +git rebase origin/main +git push --force-with-lease +\`\`\` + +**Merged PR**: ${{ github.event.pull_request.title }} +**Merged by**: ${{ github.event.pull_request.merged_by.login }} +**Link**: ${{ github.event.pull_request.html_url }} + +This issue can be closed once all active worktrees have been rebased." \ + --label "rebase-reminder,automated" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 920b4da4..1b27ff75 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,12 +1,16 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code when working with Neovim configuration. -## Neovim Configuration Structure +## Project Leadership +You are the lead Claude for the **nvim** project. You have authority to self-assign and work on issues in this repository. -This is a Neovim configuration forked from https://github.com/nvim-lua/kickstart.nvim and structured to minimize merge conflicts when updating from upstream. All custom modifications are isolated in the `lua/custom/` directory, allowing the main `init.lua` and kickstart files to be updated with minimal conflicts. +## Project Overview +A modular Neovim configuration forked from [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim), structured to minimize merge conflicts when updating from upstream. All custom modifications are isolated in the `lua/custom/` directory, allowing the main `init.lua` to stay in sync with kickstart while maintaining our customizations. -The configuration is organized in a modular structure: +**Key Design Principle**: Never modify kickstart files directly - all customizations go in `lua/custom/` to ensure clean merges from upstream. + +## Architecture - **`init.lua`**: Main configuration file that loads all settings, keymaps, and plugins - **`lua/custom/`**: Custom configuration modules @@ -18,9 +22,18 @@ The configuration is organized in a modular structure: - **`lsp.lua`**: LSP server configurations (Python, Nix, Rust, Go, C/C++) - **`clangd_helper.lua`**: Advanced clangd setup with compile_commands.json detection and file watching -## LSP Configuration +### Key Components +- **`init.lua`**: Main configuration file that loads all settings, keymaps, and plugins +- **`lua/custom/`**: Custom configuration modules + - **`options.lua`**: Custom vim options (indentation, Nerd Font settings) + - **`keymaps.lua`**: Custom key mappings + - **`plugins/`**: Plugin configurations + - **`init.lua`**: Plugin imports and basic plugin setup + - **`lsp/`**: LSP-specific configurations + - **`lsp.lua`**: LSP server configurations (Python, Nix, Rust, Go, C/C++) + - **`clangd_helper.lua`**: Advanced clangd setup with compile_commands.json detection -The LSP setup includes: +### LSP Servers Configured: - **clangd**: C/C++ with automatic compile_commands.json detection and file watching - **pyright**: Python language server with basic type checking - **nixd**: Nix language server @@ -28,54 +41,89 @@ The LSP setup includes: - **texlab**: LaTeX support - **cmake**: CMake language server -The clangd configuration in `lua/custom/plugins/lsp/clangd_helper.lua` automatically: -- Searches for compile_commands.json files using `fd` -- Watches for changes and restarts clangd when compile_commands.json is updated -- Provides a `:ReloadClangd` command for manual restart +## Development Commands -## Key Features +### Plugin Management +- `:Lazy` - Open plugin manager UI +- `:Lazy reload` - Reload plugin configurations +- `:checkhealth` - Verify all dependencies and configuration -- Uses **lazy.nvim** for plugin management -- **Blink.cmp** for autocompletion with LSP integration -- **Telescope** for fuzzy finding -- **Treesitter** for syntax highlighting -- **Which-key** for keymap help -- **Mini.nvim** modules for text objects, surround, and statusline -- **TokyoNight** colorscheme - -## Common Commands - -- `:Lazy` - Manage plugins (install, update, etc.) -- `:checkhealth` - Check Neovim configuration health -- `:ReloadClangd` - Manually restart clangd LSP server +### Search & Navigation +- `sf` - Find files (Telescope) +- `sg` - Live grep search (Telescope) - `sh` - Search help documentation -- `sf` - Find files -- `sg` - Live grep search +- `sk` - Search keymaps +- `/` - Fuzzy search in current buffer + +### Git Operations (via vim-fugitive) +- `gs` - Git status +- `gd` - Git diff +- `gc` - Git commit +- `gb` - Git blame +- `gl` - Git log +- `gp` - Git push +- `gf` - Git fetch + +### LSP Operations - `f` - Format current buffer +- `lr` - Reload all LSP servers +- `:ReloadClangd` - Manually restart clangd +- `grn` - Rename symbol +- `gra` - Code action +- `grr` - Find references +- `grd` - Go to definition -## Git Workflow +## Project-Specific Conventions +- Configuration changes are made in `lua/custom/` files +- Plugin configurations go in `lua/custom/plugins/` +- LSP servers are expected to be installed system-wide (via Nix/Home Manager) +- The configuration uses lazy loading for most plugins to optimize startup time -This project follows the standardized git workflow documented at: `../git-workflow.yaml` +## External Dependencies -Key principles: -- Never work directly on main branch -- Issue-driven development with `gh issue create` -- Always use worktrees for feature development -- Complete cleanup after merge +### System Requirements +- **git**, **make**, **unzip**, **gcc** - Basic build tools +- **ripgrep** - Fast text search (required for Telescope grep) +- **fd** - Fast file finder (required for Telescope file search) +- **Clipboard tool** - xclip/xsel on Linux, pbcopy on macOS +- **Nerd Font** - Optional but recommended for icons (currently enabled) -## Development Practices +### Neovim Plugins +- **lazy.nvim** - Plugin management +- **Blink.cmp** - Autocompletion with LSP integration +- **Telescope** - Fuzzy finding +- **Treesitter** - Syntax highlighting +- **Which-key** - Keymap help +- **Mini.nvim** - Text objects, surround, and statusline +- **TokyoNight** - Colorscheme +- **vim-fugitive** - Git integration (`:Git` commands) +- **gitsigns.nvim** - Git gutter and hunk operations +- **nvim-tmux-navigator** - Seamless tmux/nvim navigation +- **GitHub Copilot** - AI code suggestions (being replaced with zbirenbaum/copilot.lua) -Claude Code instances should follow the development practices documented at: `../development-practices.yaml` +### LSP Servers (via Nix/Home Manager) +- **clangd** - C/C++ +- **pyright** - Python type checking +- **ruff** - Python linting +- **nixd** - Nix language +- **texlab** - LaTeX +- **cmake-language-server** - CMake -This includes: -- Task management with TodoWrite -- Tool usage patterns and batching -- Debugging approaches and common bug patterns -- Code quality standards and communication guidelines +## Common Tasks +- **Add new plugin**: Create file in `lua/custom/plugins/`, add import to `lua/custom/plugins/init.lua` +- **Update LSP config**: Edit `lua/custom/plugins/lsp/lsp.lua` +- **Change keybindings**: Edit `lua/custom/keymaps.lua` +- **Update from upstream kickstart**: + ```bash + git fetch kickstart + git merge kickstart/master + # Conflicts should only be in init.lua, not in lua/custom/ + ``` +- **Disable a plugin temporarily**: Rename to `.disabled` (e.g., `avante.lua.disabled`) +- **Test plugin changes**: `:Lazy reload` or restart Neovim +- **Check health**: `:checkhealth` to verify all dependencies -## Development Workflow - -1. Configuration changes are made in `lua/custom/` files -2. Plugin configurations go in `lua/custom/plugins/` -3. LSP servers are expected to be installed system-wide (via Nix/Home Manager based on comments) -4. The configuration uses lazy loading for most plugins to optimize startup time \ No newline at end of file +## References +- Team standards: `../CLAUDE.md` +- Git workflow: `../git-workflow.yaml` +- Development practices: `../development-practices.yaml` \ No newline at end of file