Skip to content

Commit 77fdbc8

Browse files
authored
Merge pull request #18 from ready-to-review/reorg
Update outgoing sound, reorg code
2 parents a962aff + 1907143 commit 77fdbc8

28 files changed

+275
-124
lines changed

.DS_Store

0 Bytes
Binary file not shown.

.claude/CLAUDE.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Ready to Review is a macOS/Linux/Windows menubar application that helps developers track GitHub pull requests. It shows a count of incoming/outgoing PRs and highlights when you're blocking someone's review. The app integrates with the Turn API to provide intelligent PR metadata about who's actually blocking progress.
8+
9+
## Key Commands
10+
11+
### Building and Running
12+
```bash
13+
make run # Build and run (on macOS: installs to /Applications and launches)
14+
make build # Build for current platform
15+
make app-bundle # Create macOS .app bundle
16+
make install # Install to system (macOS: /Applications, Linux: /usr/local/bin, Windows: %LOCALAPPDATA%)
17+
```
18+
19+
### Development
20+
```bash
21+
make lint # Run all linters (golangci-lint with strict config + yamllint)
22+
make fix # Auto-fix linting issues where possible
23+
make deps # Download and tidy Go dependencies
24+
make clean # Remove build artifacts
25+
```
26+
27+
## Architecture Overview
28+
29+
### Core Components
30+
31+
1. **Main Application Flow** (`main.go`)
32+
- Single `context.Background()` created in main, passed through all functions
33+
- App struct holds GitHub/Turn clients, PR data, and UI state
34+
- Update loop runs every 2 minutes to refresh PR data
35+
- Menu updates only rebuild when PR data actually changes (hash-based optimization)
36+
37+
2. **GitHub Integration** (`github.go`)
38+
- Uses GitHub CLI token (`gh auth token`) for authentication
39+
- Fetches PRs with a single optimized query: `is:open is:pr involves:USER archived:false`
40+
- No pagination needed (uses 100 per page limit)
41+
42+
3. **Turn API Integration** (`cache.go`)
43+
- Provides intelligent PR metadata (who's blocking, PR size, tags)
44+
- Implements 2-hour TTL cache with SHA256-based cache keys
45+
- Cache cleanup runs daily, removes files older than 5 days
46+
- Turn API calls are made for each PR to determine blocking status
47+
48+
4. **UI Management** (`ui.go`)
49+
- System tray integration via energye/systray
50+
- Menu structure: Incoming PRs → Outgoing PRs → Settings → About
51+
- Click handlers open PRs in browser with URL validation
52+
- "Hide stale PRs" option filters PRs older than 90 days
53+
54+
5. **Platform-Specific Features**
55+
- `loginitem_darwin.go`: macOS "Start at Login" functionality via AppleScript
56+
- `loginitem_other.go`: Stub for non-macOS platforms
57+
58+
### Key Design Decisions
59+
60+
- **No Context in Structs**: Context is always passed as a parameter, never stored
61+
- **Graceful Degradation**: Turn API failures don't break the app, PRs still display
62+
- **Security**: Only HTTPS URLs allowed, whitelist of github.com and dash.ready-to-review.dev
63+
- **Minimal Dependencies**: Uses standard library where possible
64+
- **Proper Cancellation**: All goroutines respect context cancellation
65+
66+
### Linting Configuration
67+
68+
The project uses an extremely strict golangci-lint configuration (`.golangci.yml`) that enforces:
69+
- All available linters except those that conflict with Go best practices
70+
- No nolint directives without explanations
71+
- Cognitive complexity limit of 55
72+
- No magic numbers (must use constants)
73+
- Proper error handling (no unchecked errors)
74+
- No naked returns except in very short functions
75+
- Field alignment optimization for structs
76+
77+
### Special Considerations
78+
79+
1. **Authentication**: Uses GitHub CLI token, never stores it persistently
80+
2. **Caching**: Turn API responses cached to reduce API calls
81+
3. **Menu Updates**: Hash-based change detection prevents unnecessary UI updates
82+
4. **Context Handling**: Single context from main, proper cancellation in all goroutines
83+
5. **Error Handling**: All errors wrapped with context using `fmt.Errorf` with `%w`
84+
85+
When making changes:
86+
- Run `make lint` and fix all issues without adding nolint directives
87+
- Follow the strict Go style guidelines in ~/.claude/CLAUDE.md
88+
- Keep functions simple and focused
89+
- Test macOS-specific features carefully (login items, app bundle)

.claude/prompt.txt

Lines changed: 0 additions & 24 deletions
This file was deleted.

.github/SECURITY.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Security Policy
2+
3+
## Reporting a Vulnerability
4+
5+
Please follow our security reporting guidelines at:
6+
https://github.com/codeGROOVE-dev/vulnerability-reports/blob/main/SECURITY.md
7+
8+
This document contains all the specifics for how to submit a security report, including contact information, expected response times, and disclosure policies.
9+
10+
## Security Practices
11+
12+
- GitHub tokens are never logged or stored
13+
- All inputs are validated
14+
- File permissions are restricted (0600/0700)
15+
- Only HTTPS URLs to github.com are allowed
16+
- No shell interpolation of user data

.github/dependabot.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "gomod"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
open-pull-requests-limit: 5
8+
9+
- package-ecosystem: "github-actions"
10+
directory: "/"
11+
schedule:
12+
interval: "weekly"
13+
open-pull-requests-limit: 5

.github/workflows/ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
push:
7+
branches: [ main ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
name: Test
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os: [ubuntu-latest, macos-latest, windows-latest]
19+
go-version: ['1.21']
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- uses: actions/setup-go@v5
25+
with:
26+
go-version: ${{ matrix.go-version }}
27+
cache: true
28+
29+
- name: Install dependencies (Linux)
30+
if: matrix.os == 'ubuntu-latest'
31+
run: sudo apt-get update && sudo apt-get install -y gcc libgl1-mesa-dev xorg-dev
32+
33+
- name: Lint
34+
if: matrix.os != 'windows-latest'
35+
run: make lint
36+
37+
- name: Build
38+
run: make build
39+
40+
- name: Test
41+
run: go test -v -race ./...

Makefile

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
1010
BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
1111
LDFLAGS := -X main.version=$(GIT_VERSION) -X main.commit=$(GIT_COMMIT) -X main.date=$(BUILD_DATE)
1212

13-
.PHONY: build clean deps run app-bundle install install-darwin install-unix install-windows
13+
.PHONY: all build clean deps run app-bundle install install-darwin install-unix install-windows
14+
15+
# Default target
16+
all: build
1417

1518
# Install dependencies
1619
deps:
@@ -24,39 +27,38 @@ ifeq ($(shell uname),Darwin)
2427
@echo "Running $(BUNDLE_NAME) from /Applications..."
2528
@open "/Applications/$(BUNDLE_NAME).app"
2629
else
27-
go run .
30+
go run ./cmd/goose
2831
endif
2932

3033
# Build for current platform
31-
build:
34+
build: out
3235
ifeq ($(OS),Windows_NT)
33-
CGO_ENABLED=1 go build -ldflags "-H=windowsgui $(LDFLAGS)" -o $(APP_NAME).exe .
36+
CGO_ENABLED=1 go build -ldflags "-H=windowsgui $(LDFLAGS)" -o out/$(APP_NAME).exe ./cmd/goose
3437
else
35-
CGO_ENABLED=1 go build -ldflags "$(LDFLAGS)" -o $(APP_NAME) .
38+
CGO_ENABLED=1 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME) ./cmd/goose
3639
endif
3740

3841
# Build for all platforms
3942
build-all: build-darwin build-linux build-windows
4043

4144
# Build for macOS
4245
build-darwin:
43-
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-darwin-amd64 .
44-
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-darwin-arm64 .
46+
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-darwin-amd64 ./cmd/goose
47+
CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-darwin-arm64 ./cmd/goose
4548

4649
# Build for Linux
4750
build-linux:
48-
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-linux-amd64 .
49-
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-linux-arm64 .
51+
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-linux-amd64 ./cmd/goose
52+
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o out/$(APP_NAME)-linux-arm64 ./cmd/goose
5053

5154
# Build for Windows
5255
build-windows:
53-
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui $(LDFLAGS)" -o out/$(APP_NAME)-windows-amd64.exe .
56+
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui $(LDFLAGS)" -o out/$(APP_NAME)-windows-amd64.exe ./cmd/goose
5457
CGO_ENABLED=1 GOOS=windows GOARCH=arm64 go build -ldflags "-H=windowsgui $(LDFLAGS)" -o out/$(APP_NAME)-windows-arm64.exe .
5558

5659
# Clean build artifacts
5760
clean:
5861
rm -rf out/
59-
rm -f $(APP_NAME)
6062

6163
# Create out directory
6264
out:
@@ -163,7 +165,7 @@ install-darwin: app-bundle
163165
install-unix: build
164166
@echo "Installing on $(shell uname)..."
165167
@echo "Installing binary to /usr/local/bin..."
166-
@sudo install -m 755 $(APP_NAME) /usr/local/bin/
168+
@sudo install -m 755 out/$(APP_NAME) /usr/local/bin/
167169
@echo "Installation complete! $(APP_NAME) has been installed to /usr/local/bin"
168170

169171
# Install on Windows
@@ -172,7 +174,7 @@ install-windows: build
172174
@echo "Creating program directory..."
173175
@if not exist "%LOCALAPPDATA%\Programs\$(APP_NAME)" mkdir "%LOCALAPPDATA%\Programs\$(APP_NAME)"
174176
@echo "Copying executable..."
175-
@copy /Y "$(APP_NAME).exe" "%LOCALAPPDATA%\Programs\$(APP_NAME)\"
177+
@copy /Y "out\$(APP_NAME).exe" "%LOCALAPPDATA%\Programs\$(APP_NAME)\"
176178
@echo "Installation complete! $(APP_NAME) has been installed to %LOCALAPPDATA%\Programs\$(APP_NAME)"
177179
@echo "You may want to add %LOCALAPPDATA%\Programs\$(APP_NAME) to your PATH environment variable."
178180
# BEGIN: lint-install .

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ The only PR tracker that honks at you when you're the bottleneck. Now shipping w
99

1010
Lives in your menubar like a tiny waterfowl of productivity shame, watching your GitHub PRs and making aggressive bird sounds when you're blocking someone's code from seeing the light of production.
1111

12-
> ⚠️ **EXPERIMENTAL**: This is very much a work in progress. The blocking logic has bugs. It theoretically runs on Linux, BSD, and Windows but we've literally never tested it there. Here be dragons (and geese).
12+
> ⚠️ **EXPERIMENTAL**: This is very much a work in progress. The blocking logic has bugs. Linux/BSD/Windows support is untested. Here be dragons (and geese).
1313
1414
![PR Menubar Screenshot](media/screenshot.png)
1515

1616
## What It Does
1717

1818
- **🪿 Honks** when you're blocking someone's PR (authentic goose noises included)
19-
- **🚀 Rocket sounds** when own your own PR is ready to go to the next stage
19+
- **✈️ Jet sounds** when your own PR is ready for the next stage
2020
- **🧠 Smart turn-based assignment** - knows who is blocking a PR, knows when tests are failing, etc.
2121
- **⭐ Auto-start** on login (macOS)
2222

@@ -71,7 +71,6 @@ When `GITHUB_TOKEN` is set, the goose will use it directly instead of the GitHub
7171
## Known Issues
7272

7373
- Blocking logic isn't 100% accurate (we're working on it)
74-
- Linux/BSD/Windows support likely works, but remains untested
7574
- The goose may not stop honking until you review your PRs
7675
- Visual notifications won't work on macOS until we sign the binary
7776

@@ -83,9 +82,9 @@ This tool is part of the [CodeGroove](https://codegroove.dev) developer accelera
8382

8483
## Privacy
8584

86-
- Your GitHub token is used to fetch PR metadata, but is never stored or logged.
87-
- We won't sell your information or use it for any purpose other than caching.
88-
- GitHub metadata for open pull requests may be cached for up to 20 days for performance reasons.
85+
- Your GitHub token is never stored or logged
86+
- PR metadata cached for up to 20 days (performance)
87+
- No telemetry or external data collection
8988

9089
---
9190

6 KB
Binary file not shown.
File renamed without changes.

0 commit comments

Comments
 (0)