add more opencode goodness

This commit is contained in:
Nate Anderson 2025-10-27 11:56:29 -06:00
parent 143b45999a
commit 8ccd91a459
11 changed files with 860 additions and 13 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
**/node_modules/**

12
flake.lock generated
View File

@ -98,11 +98,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1760878510, "lastModified": 1761373498,
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -114,11 +114,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1761016216, "lastModified": 1761468971,
"narHash": "sha256-G/iC4t/9j/52i/nm+0/4ybBmAF4hzR8CNHC75qEhjHo=", "narHash": "sha256-vY2OLVg5ZTobdroQKQQSipSIkHlxOTrIF1fsMzPh8w8=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "481cf557888e05d3128a76f14c76397b7d7cc869", "rev": "78e34d1667d32d8a0ffc3eba4591ff256e80576e",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -345,6 +345,7 @@
"waybar".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/waybar"; "waybar".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/waybar";
# Shared # Shared
"helix".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/shared/linked-dotfiles/helix"; "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 # Theme files
"gtk-4.0/assets".source = "${config.gtk.theme.package}/share/themes/${config.gtk.theme.name}/gtk-4.0/assets"; "gtk-4.0/assets".source = "${config.gtk.theme.package}/share/themes/${config.gtk.theme.name}/gtk-4.0/assets";

View File

@ -1,5 +1,5 @@
# Catppuccin Macchiato Minimal - Judicious Syntax Highlighting # 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 # Functions and variables remain plain text for reduced visual noise
"ui.background" = { bg = "base" } "ui.background" = { bg = "base" }
@ -98,7 +98,7 @@
"variable.parameter" = "text" "variable.parameter" = "text"
"variable.other.member" = "text" "variable.other.member" = "text"
"type" = "lavender" # Types are slightly highlighted "type" = { fg = "lavender", modifiers = ["italic"]} # Types are slightly highlighted
"type.builtin" = "lavender" "type.builtin" = "lavender"
"constructor" = "text" # Constructors are plain text "constructor" = "text" # Constructors are plain text

View File

@ -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

View File

@ -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=="],
}
}

View File

@ -1,11 +1,25 @@
{ {
"$schema": "https://opencode.ai/config.json", "$schema": "https://opencode.ai/config.json",
// Theme configuration
"theme": "catppuccin", "theme": "catppuccin",
"model": "anthropic/claude-sonnet-4-5", "model": "anthropic/claude-sonnet-4-5",
"autoupdate": false, "autoupdate": false,
"plugin": [ "plugin": [], // local plugins do not need to be added here
// "skills" "agent": {
// "swaync-notifications" // "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
}
}
} }

View File

@ -0,0 +1,6 @@
{
"dependencies": {
"@opencode-ai/plugin": "0.15.2",
"gray-matter": "^4.0.3"
}
}

View File

@ -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="<cloud-id>" \
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="<cloud-id>" \
issueIdOrKey="PI-XXXXX" \
transition='{"id": "41"}' # In Progress transition ID
```
Add comment explaining work start:
```bash
atlassian-mcp-server_addCommentToJiraIssue \
cloudId="<cloud-id>" \
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 <repo-name>/develop
# Pull latest changes
git pull
# Create worktree with proper naming
# Pattern: ../<descriptive-name> with branch nate/PI-XXXXX_descriptive-name
git worktree add ../<descriptive-name> -b nate/PI-XXXXX_descriptive-name
# Navigate to new worktree
cd ../<descriptive-name>
```
**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)
<run-test-command>
```
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
<run-test-command>
```
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
<full-test-command>
# Run linting (if available)
<lint-command>
# Run type checking (if available)
<typecheck-command>
```
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: <concise description>
<detailed explanation of changes>
- What was changed
- Why it was changed
- How it addresses the ticket"
```
**Commit message format:**
- First line: `PI-XXXXX: <summary>` (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: <descriptive title>" \
--body "$(cat <<'PRBODY'
## Summary
- Fixes issue described in PI-XXXXX
- Implements <feature/fix> using TDD approach
## Changes
- Added tests for <functionality>
- Implemented <feature/fix>
- 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="<cloud-id>" \
issueIdOrKey="PI-XXXXX" \
commentBody="Draft PR created: <pr-url>
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.

View File

@ -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 <repo>/develop
git pull
# Create new worktree
git worktree add <path> -b <branch-name>
```
### List Worktrees
```bash
git worktree list
```
### Remove Worktree
```bash
# From any location in repo
git worktree remove <path>
# Or manually
rm -rf <path>
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: `<username>/PI-XXXXX_<description>`
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 <path>
git worktree prune
```
### Branch Already Exists
```bash
# Error: branch already exists
# Solution: Use existing branch or delete old one
git worktree add <path> <existing-branch>
# Or delete old branch
git branch -D <branch-name>
git worktree add <path> -b <branch-name>
```
### Locked Worktree
```bash
# If worktree shows as locked
git worktree unlock <path>
git worktree remove <path>
```
### 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 <path>
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
```

View File

@ -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_<function>_<scenario>_<expected_result>
```
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, '<script>alert(1)</script>');
expect(response.status).toBe(200);
expect(response.data.name).not.toContain('<script>');
});
```
## TDD Best Practices
### Start Simple
Write simplest test first, then add complexity:
1. Happy path with minimal data
2. Add edge cases
3. Add error conditions
4. Add integration scenarios
### One Test at a Time
- Write one test
- Watch it fail
- Make it pass
- Refactor if needed
- Repeat
### Keep Tests Independent
```javascript
// ❌ Bad - Tests depend on order
test('create_folder', () => { /* creates folder with id=1 */ });
test('rename_folder', () => { /* assumes folder id=1 exists */ });
// ✅ Good - Each test sets up own data
test('create_folder', () => {
const folder = createFolder();
expect(folder.id).toBeDefined();
});
test('rename_folder', () => {
const folder = createFolder(); // Own setup
const result = renameFolder(folder.id, 'NewName');
expect(result.name).toBe('NewName');
});
```
### Test Behavior, Not Implementation
```javascript
// ❌ Bad - Tests internal implementation
test('uses_postgres_query', () => {
expect(mockDb.query).toHaveBeenCalledWith('UPDATE folders...');
});
// ✅ Good - Tests behavior
test('rename_updates_folder_name', () => {
renameFolder(folderId, 'NewName');
const folder = getFolder(folderId);
expect(folder.name).toBe('NewName');
});
```
## When to Refactor
Refactor when tests are green and you notice:
- Duplication
- Long functions
- Unclear variable names
- Complex conditionals
- Hard-coded values
**Always keep tests passing during refactoring**
## Handling Legacy Code
When adding tests to existing code without tests:
1. Write characterization tests (document current behavior)
2. Refactor to make code testable
3. Add tests for new functionality
4. Gradually improve test coverage
## Test Coverage
Aim for coverage of:
- All new code paths
- Bug fixes (test the bug scenario)
- Edge cases
- Error conditions
Not aiming for 100% - focus on meaningful coverage.