diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0979a6c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/node_modules/** diff --git a/flake.lock b/flake.lock index 615b141..41e3e11 100644 --- a/flake.lock +++ b/flake.lock @@ -98,11 +98,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1760878510, - "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", + "lastModified": 1761373498, + "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", + "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", "type": "github" }, "original": { @@ -114,11 +114,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1761016216, - "narHash": "sha256-G/iC4t/9j/52i/nm+0/4ybBmAF4hzR8CNHC75qEhjHo=", + "lastModified": 1761468971, + "narHash": "sha256-vY2OLVg5ZTobdroQKQQSipSIkHlxOTrIF1fsMzPh8w8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "481cf557888e05d3128a76f14c76397b7d7cc869", + "rev": "78e34d1667d32d8a0ffc3eba4591ff256e80576e", "type": "github" }, "original": { diff --git a/nate-work/modules/home-manager/home.nix b/nate-work/modules/home-manager/home.nix index e1b7486..1ea5097 100644 --- a/nate-work/modules/home-manager/home.nix +++ b/nate-work/modules/home-manager/home.nix @@ -345,6 +345,7 @@ "waybar".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/waybar"; # Shared "helix".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/shared/linked-dotfiles/helix"; + "opencode".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/shared/linked-dotfiles/opencode"; # Theme files "gtk-4.0/assets".source = "${config.gtk.theme.package}/share/themes/${config.gtk.theme.name}/gtk-4.0/assets"; diff --git a/shared/linked-dotfiles/helix/themes/catppuccin_macchiato_minimal.toml b/shared/linked-dotfiles/helix/themes/catppuccin_macchiato_minimal.toml index c29e118..baca34f 100644 --- a/shared/linked-dotfiles/helix/themes/catppuccin_macchiato_minimal.toml +++ b/shared/linked-dotfiles/helix/themes/catppuccin_macchiato_minimal.toml @@ -1,5 +1,5 @@ # Catppuccin Macchiato Minimal - Judicious Syntax Highlighting -# Uses only 4 colors for syntax: lavender (keywords), green (strings), peach (numbers), mauve (comments) +# Uses only 4 colors for syntax # Functions and variables remain plain text for reduced visual noise "ui.background" = { bg = "base" } @@ -98,7 +98,7 @@ "variable.parameter" = "text" "variable.other.member" = "text" -"type" = "lavender" # Types are slightly highlighted +"type" = { fg = "lavender", modifiers = ["italic"]} # Types are slightly highlighted "type.builtin" = "lavender" "constructor" = "text" # Constructors are plain text diff --git a/shared/linked-dotfiles/opencode/agent/pr-reviewer.md b/shared/linked-dotfiles/opencode/agent/pr-reviewer.md new file mode 100644 index 0000000..225381a --- /dev/null +++ b/shared/linked-dotfiles/opencode/agent/pr-reviewer.md @@ -0,0 +1,59 @@ +--- +description: Reviews pull requests to verify work is ready for team review - runs comprehensive validation checks and provides approval or feedback +mode: subagent +model: anthropic/claude-sonnet-4-5 +temperature: 0.1 +tools: + write: false + edit: false + bash: true +permission: + bash: + "make *": allow + "gh pr *": allow + "rg *": allow + "test *": allow + "grep *": allow + "*": ask +--- + +You are a pull request reviewer. Your job is to verify that work is ready for human code review. + +## Your Process + +1. **Verify the work is ready for review** + - Check that the PR exists and is accessible + - Confirm changes are committed and pushed + - Ensure PR description is complete + +2. **Use the go-pr-review skill** + - Invoke the `go-pr-review` skill to perform comprehensive validation + - The skill will check repository compatibility, run tests, validate code quality + - Trust the skill's validation results + +3. **Provide your conclusion** + - If go-pr-review finds critical issues: Report "Needs work" with specific issues to fix + - If go-pr-review approves or has only minor suggestions: Report "Ready for review" + - Always include a brief summary of what was validated + +## Important Guidelines + +- Be thorough but efficient - rely on the go-pr-review skill for detailed checks +- Never modify code - you're reviewing only +- Provide actionable feedback if issues are found +- Be clear about whether work can proceed to human review or needs fixes first + +## Response Format + +Conclude your review with one of: + +**✅ Ready for review** +- All validations passed +- Code quality meets standards +- Tests are passing +- Ready for human code review + +**❌ Needs work** +- [List critical issues that must be fixed] +- [Provide specific guidance on what to address] +- Re-review after fixes are applied diff --git a/shared/linked-dotfiles/opencode/bun.lock b/shared/linked-dotfiles/opencode/bun.lock new file mode 100644 index 0000000..be4b108 --- /dev/null +++ b/shared/linked-dotfiles/opencode/bun.lock @@ -0,0 +1,17 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "dependencies": { + "@opencode-ai/plugin": "0.15.2", + }, + }, + }, + "packages": { + "@opencode-ai/plugin": ["@opencode-ai/plugin@0.15.2", "", { "dependencies": { "@opencode-ai/sdk": "0.15.2", "zod": "4.1.8" } }, "sha512-cCttqxDou+OPQzjc20cB4xxuSMMSowZMpvlioIgyzyhp8B7Gc5hh1kY796nly7vjaQfUcLg8pOmRJSLrbxj98g=="], + + "@opencode-ai/sdk": ["@opencode-ai/sdk@0.15.2", "", {}, "sha512-m2aU0TiZj7/o1JvYmoqF7ichrKZcWi4UTx3WYlDXpRJvfZX0gnLKLJAlTKfHkisytGlrlgmST2kt/YQrAjc0wQ=="], + + "zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + } +} diff --git a/shared/linked-dotfiles/opencode/opencode.jsonc b/shared/linked-dotfiles/opencode/opencode.jsonc index f6c44d1..6e13652 100644 --- a/shared/linked-dotfiles/opencode/opencode.jsonc +++ b/shared/linked-dotfiles/opencode/opencode.jsonc @@ -1,11 +1,25 @@ { "$schema": "https://opencode.ai/config.json", - // Theme configuration "theme": "catppuccin", "model": "anthropic/claude-sonnet-4-5", "autoupdate": false, - "plugin": [ - // "skills" - // "swaync-notifications" - ] + "plugin": [], // local plugins do not need to be added here + "agent": { + // "pr-reviewer": { + // "description": "Reviews pull requests to verify work is ready for team review", + // "mode": "subagent", + // } + }, + "mcp": { + "atlassian-mcp-server": { + "type": "local", + "command": [ + "npx", + "-y", + "mcp-remote", + "https://mcp.atlassian.com/v1/sse" + ], + "enabled": true + } + } } \ No newline at end of file diff --git a/shared/linked-dotfiles/opencode/package.json b/shared/linked-dotfiles/opencode/package.json new file mode 100644 index 0000000..3683e05 --- /dev/null +++ b/shared/linked-dotfiles/opencode/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@opencode-ai/plugin": "0.15.2", + "gray-matter": "^4.0.3" + } +} diff --git a/shared/linked-dotfiles/opencode/skills/do-job/SKILL.md b/shared/linked-dotfiles/opencode/skills/do-job/SKILL.md new file mode 100644 index 0000000..512f661 --- /dev/null +++ b/shared/linked-dotfiles/opencode/skills/do-job/SKILL.md @@ -0,0 +1,340 @@ +--- +name: do-job +description: Use when starting work on Jira tickets - fetches To Do tickets, creates git worktrees with proper PI-XXXXX naming, implements features using TDD (test-first), commits with ticket references, creates draft PRs, validates work with PR review, and transitions tickets through workflow to Testing +--- + +# Do Job + +Complete developer workflow from ticket selection to validated draft PR using TDD and git worktrees. + +## When to Use This Skill + +Use when: +- Starting work on a new Jira ticket +- Need to set up development environment for ticket work +- Implementing features using test-driven development +- Creating PRs for Jira-tracked work + +## Workflow Checklist + +Copy and track progress: + +``` +Ticket Workflow Progress: +- [ ] Step 1: Fetch and select To Do ticket +- [ ] Step 2: Move ticket to In Progress +- [ ] Step 3: Set up git worktree +- [ ] Step 4: Write failing tests (TDD) +- [ ] Step 5: Implement feature/fix +- [ ] Step 6: Verify tests pass +- [ ] Step 7: Commit with PI-XXXXX reference +- [ ] Step 8: Push branch +- [ ] Step 9: Create draft PR +- [ ] Step 10: Review work with PR reviewer +- [ ] Step 11: Link PR to ticket +``` + +## Prerequisites + +Verify environment: + +```bash +# Check Jira access +atlassian-mcp-server_getAccessibleAtlassianResources + +# Check GitHub CLI +gh auth status + +# Verify in repos root directory +ls -d */ +``` + +## Step 1: Fetch and Select Ticket + +```bash +# Get To Do tickets +atlassian-mcp-server_searchJiraIssuesUsingJql \ + cloudId="" \ + jql="assignee = currentUser() AND status = 'To Do' ORDER BY priority DESC, updated DESC" \ + fields='["summary", "description", "status", "priority"]' +``` + +Review tickets and select one based on priority and description. + +## Step 2: Move Ticket to In Progress + +```bash +atlassian-mcp-server_transitionJiraIssue \ + cloudId="" \ + issueIdOrKey="PI-XXXXX" \ + transition='{"id": "41"}' # In Progress transition ID +``` + +Add comment explaining work start: + +```bash +atlassian-mcp-server_addCommentToJiraIssue \ + cloudId="" \ + issueIdOrKey="PI-XXXXX" \ + commentBody="Starting work on this ticket using TDD approach" +``` + +## Step 3: Set Up Git Worktree + +**CRITICAL: All branches and commits MUST include PI-XXXXX ticket number** + +### Identify Repository + +From repos root directory, determine which repo based on ticket description and summary. + +### Create Worktree + +```bash +# Navigate to develop branch of target repo +cd /develop + +# Pull latest changes +git pull + +# Create worktree with proper naming +# Pattern: ../ with branch nate/PI-XXXXX_descriptive-name +git worktree add ../ -b nate/PI-XXXXX_descriptive-name + +# Navigate to new worktree +cd ../ +``` + +**Naming conventions:** +- Directory: Short descriptive name (e.g., `rename-folder-fix`) +- Branch: `nate/PI-XXXXX_descriptive-name` (e.g., `nate/PI-70535_rename-folder-fix`) +- **MUST include PI-XXXXX** in branch name + +## Step 4: Build Implementation Plan + +Analyze ticket requirements and create TDD plan: + +1. **Understand requirements** from ticket description +2. **Identify affected code** areas +3. **Plan test cases** covering: + - Happy path + - Edge cases + - Error conditions +4. **Plan implementation** approach + +## Step 5: TDD Implementation + +### Write Failing Tests First + +**CRITICAL: Write tests BEFORE implementation** + +```bash +# Identify test framework from repo +ls *_test.* test/ tests/ __tests__/ + +# Create or modify test file +# Write test that validates missing functionality +``` + +Test should: +- Clearly describe expected behavior +- Cover the specific bug/feature from ticket +- **Fail initially** (validates test is working) + +### Run Failing Tests + +```bash +# Verify test fails (proves test is valid) + +``` + +Expected: Test fails with clear error showing missing functionality. + +### Implement Feature/Fix + +Write minimal code to make test pass: + +```bash +# Implement the feature or fix +# Focus on making test pass, not perfection +``` + +### Run Tests Again + +```bash +# Verify test now passes + +``` + +Expected: All tests pass. + +### Refactor (if needed) + +Clean up implementation while keeping tests passing: + +- Improve code clarity +- Remove duplication +- Follow project conventions +- **Keep tests passing** + +## Step 6: Verify Complete Solution + +```bash +# Run full test suite + + +# Run linting (if available) + + +# Run type checking (if available) + +``` + +All checks must pass before proceeding. + +## Step 7: Commit Changes + +**CRITICAL: Commit message MUST include PI-XXXXX** + +```bash +# Stage changes +git add . + +# Commit with ticket reference +git commit -m "PI-XXXXX: + + +- What was changed +- Why it was changed +- How it addresses the ticket" +``` + +**Commit message format:** +- First line: `PI-XXXXX: ` (50 chars max) +- Blank line +- Detailed description explaining the why and how +- Reference ticket number (PI-XXXXX) in first line + +## Step 8: Push Branch + +```bash +# Push to remote +git push -u origin nate/PI-XXXXX_descriptive-name +``` + +## Step 9: Create Draft PR + +```bash +# Create draft PR with gh CLI +gh pr create \ + --draft \ + --title "PI-XXXXX: " \ + --body "$(cat <<'PRBODY' +## Summary +- Fixes issue described in PI-XXXXX +- Implements using TDD approach + +## Changes +- Added tests for +- Implemented +- Verified all tests pass + +## Testing +- [x] Unit tests added and passing +- [x] Linting passes +- [x] Manual testing completed + +## Jira +Related ticket: PI-XXXXX + +## Notes +Ready for review. Once approved, will move ticket to Pull Request status. +PRBODY +)" +``` + +**Save PR URL** returned by command for next steps. + +## Step 10: Review Work with PR Reviewer + +**CRITICAL: Invoke @pr-reviewer subagent to validate work before linking to ticket** + +```bash +# Invoke the pr-reviewer subagent +@pr-reviewer please review the PR I just created +``` + +The pr-reviewer will: +- Verify the repository is compatible (Go with Makefile) +- Run all validation commands (tests, linting, type checking) +- Review code quality against project standards +- Check for security issues and best practices +- Provide verdict: Ready for review OR needs work + +**If pr-reviewer finds issues:** +1. Address the critical issues identified +2. Re-run tests and validations +3. Commit fixes with `PI-XXXXX: Address PR review feedback` +4. Push updates +5. Invoke @pr-reviewer again to re-validate + +**Only proceed to Step 11 when pr-reviewer gives approval.** + +## Step 11: Link PR to Ticket + +```bash +# Add PR link to Jira ticket +atlassian-mcp-server_addCommentToJiraIssue \ + cloudId="" \ + issueIdOrKey="PI-XXXXX" \ + commentBody="Draft PR created: + +Implementation complete using TDD approach. Ready for code review." +``` + +## Post-Workflow Steps (Manual) + +**After automated pr-reviewer approval and manual developer review:** + +1. Remove draft status from PR +2. Request code review from team +3. Address any additional review comments +4. Get approval +5. **Manual:** Transition ticket to "Pull Request" status (transition ID: 381) +6. **Manual:** After merge, SDET moves to "Testing (Service Stack)" (transition ID: 201) + +## Common Mistakes + +### Branch Naming +- ❌ `fix-bug` (missing ticket number) +- ❌ `PI70535-fix` (missing hyphen, no username) +- ✅ `nate/PI-70535_rename-folder-fix` + +### Commit Messages +- ❌ `fixed bug` (no ticket reference) +- ❌ `Updated code for PI-70535` (vague) +- ✅ `PI-70535: Fix shared folder rename permission check` + +### TDD Order +- ❌ Write code first, then tests +- ❌ Skip tests entirely +- ✅ Write failing test → Implement → Verify passing → Refactor + +### Worktree Location +- ❌ `git worktree add ./feature` (wrong location) +- ❌ `git worktree add ~/feature` (absolute path) +- ✅ `git worktree add ../feature-name` (parallel to develop) + +## Jira Transition IDs + +Reference for manual transitions: + +- To Do: 11 +- In Progress: 41 +- Pull Request: 381 +- Testing (Service Stack): 201 +- Done: (varies by project) + +## Reference Materials + +See references/tdd-workflow.md for detailed TDD best practices. +See references/git-worktree.md for git worktree patterns and troubleshooting. diff --git a/shared/linked-dotfiles/opencode/skills/do-job/references/git-worktree.md b/shared/linked-dotfiles/opencode/skills/do-job/references/git-worktree.md new file mode 100644 index 0000000..2b41997 --- /dev/null +++ b/shared/linked-dotfiles/opencode/skills/do-job/references/git-worktree.md @@ -0,0 +1,236 @@ +# Git Worktree Patterns + +## Overview + +Git worktrees allow multiple working directories from single repository, enabling parallel work on different branches without stashing or switching. + +## Basic Commands + +### Create Worktree + +```bash +# From main/develop branch +cd /develop +git pull + +# Create new worktree +git worktree add -b +``` + +### List Worktrees + +```bash +git worktree list +``` + +### Remove Worktree + +```bash +# From any location in repo +git worktree remove + +# Or manually +rm -rf +git worktree prune +``` + +## Naming Patterns + +### Directory Structure + +``` +repos/ +├── document-api/ +│ ├── develop/ # Main worktree +│ ├── fix-permissions/ # Feature worktree +│ └── add-tags/ # Another feature worktree +``` + +### Branch Naming + +Format: `/PI-XXXXX_` + +Examples: +- `nate/PI-70535_rename-folder-fix` +- `nate/PI-70361_upload-permissions` +- `nate/PI-69924_delete-access-level` + +## Workflow Patterns + +### Starting Work + +```bash +# Navigate to develop +cd document-api/develop + +# Update develop +git pull + +# Create worktree for ticket +git worktree add ../pi-70535-rename-fix -b nate/PI-70535_rename-folder-fix + +# Move to worktree +cd ../pi-70535-rename-fix +``` + +### During Work + +```bash +# Normal git operations work in worktree +git status +git add . +git commit -m "PI-70535: Fix folder rename permissions" +git push -u origin nate/PI-70535_rename-folder-fix +``` + +### After PR Merge + +```bash +# From anywhere in repo +git worktree remove ../pi-70535-rename-fix + +# Clean up +git worktree prune +git branch -d nate/PI-70535_rename-folder-fix + +# Update develop +cd develop +git pull +``` + +## Common Issues + +### Worktree Already Exists + +```bash +# Error: worktree already exists +# Solution: Remove old worktree first +git worktree remove +git worktree prune +``` + +### Branch Already Exists + +```bash +# Error: branch already exists +# Solution: Use existing branch or delete old one +git worktree add + +# Or delete old branch +git branch -D +git worktree add -b +``` + +### Locked Worktree + +```bash +# If worktree shows as locked +git worktree unlock +git worktree remove +``` + +### Orphaned Worktrees + +```bash +# Clean up references to deleted worktrees +git worktree prune +``` + +## Best Practices + +### Keep Worktrees Short-Lived + +- Create for specific ticket +- Remove after PR merged +- Don't accumulate many worktrees + +### Use Descriptive Names + +```bash +# ❌ Bad +git worktree add ../work -b fix + +# ✅ Good +git worktree add ../rename-folder-fix -b nate/PI-70535_rename-folder-fix +``` + +### Always Branch from Latest + +```bash +# Update base branch before creating worktree +cd develop +git pull +git worktree add ../feature -b username/PI-XXXXX_feature +``` + +### Clean Up Regularly + +```bash +# List all worktrees +git worktree list + +# Remove merged/abandoned worktrees +git worktree remove +git worktree prune +``` + +## Advantages Over Branch Switching + +### Parallel Work + +Work on multiple tickets simultaneously without switching contexts: + +``` +Terminal 1: cd document-api/develop # Review PRs +Terminal 2: cd document-api/feature-1 # Active development +Terminal 3: cd document-api/hotfix # Emergency fix +``` + +### Preserve State + +Each worktree maintains its own: +- Working directory state +- Staged changes +- Build artifacts +- IDE configuration + +### Avoid Stashing + +No need to stash changes when switching tasks: + +```bash +# Traditional flow (with stashing) +git stash +git checkout other-branch +# ... do work ... +git checkout original-branch +git stash pop + +# Worktree flow (no stashing) +cd ../other-worktree +# ... do work ... +cd ../original-worktree +# Everything still there +``` + +## Limitations + +### Shared References + +All worktrees share: +- Git objects +- Remote configuration +- Git hooks +- Submodules + +### Disk Space + +Each worktree requires full working directory (but shares `.git` objects). + +### Cannot Checkout Same Branch + +```bash +# Error: branch already checked out +# One branch can only be checked out in one worktree at a time +git worktree add ../dup -b existing-branch # Fails if already checked out +``` diff --git a/shared/linked-dotfiles/opencode/skills/do-job/references/tdd-workflow.md b/shared/linked-dotfiles/opencode/skills/do-job/references/tdd-workflow.md new file mode 100644 index 0000000..7b3ca55 --- /dev/null +++ b/shared/linked-dotfiles/opencode/skills/do-job/references/tdd-workflow.md @@ -0,0 +1,173 @@ +# Test-Driven Development Workflow + +## Core TDD Cycle + +1. **Red** - Write failing test +2. **Green** - Make test pass +3. **Refactor** - Improve code while keeping tests passing + +## Writing Effective Tests + +### Test Structure + +``` +# Arrange - Set up test data and conditions +# Act - Execute the code being tested +# Assert - Verify expected behavior +``` + +### Good Test Characteristics + +- **Isolated** - Tests don't depend on each other +- **Repeatable** - Same input always produces same output +- **Fast** - Tests run quickly +- **Clear** - Test name describes what's being tested +- **Focused** - One concept per test + +### Test Naming + +``` +test___ +``` + +Examples: +- `test_rename_folder_as_owner_succeeds` +- `test_rename_folder_without_permission_returns_403` +- `test_rename_folder_with_empty_name_returns_400` + +## Common Patterns + +### Testing Error Conditions + +```javascript +// Test expected errors +test('rename_folder_without_permission_returns_403', async () => { + // Arrange: Set up user without permissions + const user = createUserWithoutPermissions(); + + // Act: Attempt rename + const response = await renameFolder(user, folderId, newName); + + // Assert: Verify 403 error + expect(response.status).toBe(403); + expect(response.error).toContain('forbidden'); +}); +``` + +### Testing Happy Path + +```javascript +test('rename_folder_as_owner_succeeds', async () => { + // Arrange: Set up folder with owner + const owner = createOwner(); + const folder = createFolder(owner); + + // Act: Rename folder + const response = await renameFolder(owner, folder.id, 'NewName'); + + // Assert: Verify success + expect(response.status).toBe(200); + expect(response.data.name).toBe('NewName'); +}); +``` + +### Testing Edge Cases + +```javascript +test('rename_folder_with_special_characters_sanitizes_name', async () => { + const owner = createOwner(); + const folder = createFolder(owner); + + const response = await renameFolder(owner, folder.id, ''); + + expect(response.status).toBe(200); + expect(response.data.name).not.toContain('