Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

Ready to Review is an elegant modern Slack bot written in Go that integrates with GitHub to streamline PR review workflows. The bot provides real-time notifications, dashboard views, and multi-org/multi-Slack support.
reviewGOOSE:Slack is the Slack integration for reviewGOOSE — an elegant modern Slack bot written in Go that integrates with GitHub to streamline PR review workflows. The bot provides real-time notifications, dashboard views, and multi-org/multi-Slack support.

## Core Features

Expand All @@ -27,7 +27,7 @@ Ready to Review is an elegant modern Slack bot written in Go that integrates wit
- Native Slack app home tab with Block Kit UI showing incoming/outgoing PRs
- Highlights PRs blocked on the user
- Clean, settings-free interface focusing on PR status
- Alternative web dashboard available at https://dash.ready-to-review.dev/
- Alternative web dashboard available at https://reviewgoose.dev/

### 3. Smart Notifications
- **Smart DM Logic**: If user tagged in channel, delay DMs by configured time (default: 65min)
Expand Down Expand Up @@ -92,7 +92,7 @@ make clean # Clean build artifacts

### External Dependencies
- `github.com/codeGROOVE-dev/sprinkler` - WebSocket hub for GitHub webhook events
- `github.com/ready-to-review/turnclient` - PR state analysis and blocking detection
- `github.com/codeGROOVE-dev/turnclient` - PR state analysis and blocking detection
- `github.com/slack-go/slack` - Official Slack API client
- `github.com/google/go-github/v50` - GitHub API client

Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Ready-to-Review Slacker
# reviewGOOSE:Slack

[![Go Report Card](https://goreportcard.com/badge/github.com/codeGROOVE-dev/slacker)](https://goreportcard.com/report/github.com/codeGROOVE-dev/slacker)
[![GoDoc](https://godoc.org/github.com/codeGROOVE-dev/slacker?status.svg)](https://godoc.org/github.com/codeGROOVE-dev/slacker)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Go Version](https://img.shields.io/github/go-mod/go-version/codeGROOVE-dev/slacker)](go.mod)

![Ready-to-Review Slacker](media/Slackerposter.jpg)
![reviewGOOSE:Slack](media/Slackerposter.jpg)

Slack bot that tracks GitHub pull requests and notifies reviewers when it's their turn. Part of the https://codegroove.dev/ ecosystem of developer acceleration tools.
The Slack integration for [reviewGOOSE](https://codegroove.dev/reviewgoose/) — know instantly when you're blocking a PR.

**reviewGOOSE:Slack** tracks GitHub pull requests and notifies reviewers when it's their turn. Works alongside [reviewGOOSE:Desktop](https://github.com/codeGROOVE-dev/goose) for a complete PR tracking experience. Part of the [codeGROOVE](https://codegroove.dev/) ecosystem.

## Quick Start

Expand Down Expand Up @@ -137,10 +139,10 @@ channels:
## Usage

Slack commands:
- `/r2r dashboard` - View your PR dashboard
- `/r2r help` - Show help
- `/goose dashboard` - View your PR dashboard
- `/goose help` - Show help

The dashboard is also available in the app's Home tab or at https://dash.ready-to-review.dev/
The dashboard is also available in the app's Home tab or at https://reviewgoose.dev/

## Smart Notification Logic

Expand Down
2 changes: 1 addition & 1 deletion cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func run(ctx context.Context, cancel context.CancelFunc, cfg *config.ServerConfi
homeHandler := slack.NewHomeHandler(slackManager, githubManager, configManager, stateStore, reverseMapping)
slackManager.SetHomeViewHandler(homeHandler.HandleAppHomeOpened)

// Initialize report handler for /r2r report slash command
// Initialize report handler for /goose report slash command
reportHandler := slack.NewReportHandler(slackManager, githubManager, stateStore, reverseMapping)
slackManager.SetReportHandler(reportHandler.HandleReportCommand)

Expand Down
6 changes: 3 additions & 3 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Deployment Guide

This guide is for self-hosting Ready-to-Review. If you're using the SaaS version, see [SETUP.md](SETUP.md) instead.
This guide is for self-hosting reviewGOOSE:Slack. If you're using the SaaS version, see [SETUP.md](SETUP.md) instead.

## Architecture Overview

Ready-to-Review consists of two services:
reviewGOOSE:Slack consists of two services:

1. **slacker** - Main bot server that handles GitHub webhooks and Slack notifications
2. **slacker-registrar** - OAuth-only service for multi-workspace installations
Expand Down Expand Up @@ -44,7 +44,7 @@ Ready-to-Review consists of two services:
1. Go to https://api.slack.com/apps
2. Click **"Create New App"**
3. Choose **"From scratch"**
4. Name your app (e.g., "Ready-to-Review")
4. Name your app (e.g., "reviewGOOSE")
5. Select your development workspace

### Step 2: Configure OAuth & Permissions
Expand Down
24 changes: 12 additions & 12 deletions docs/SETUP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Getting Started with Ready-to-Review
# Getting Started with reviewGOOSE:Slack

Ready-to-Review is a Slack bot that keeps your team informed about GitHub pull requests. It creates threads for PRs, tracks their status with emojis, and sends smart notifications so reviewers know when it's their turn.
reviewGOOSE:Slack is the Slack integration for [reviewGOOSE](https://codegroove.dev/reviewgoose/) — it keeps your team informed about GitHub pull requests. It creates threads for PRs, tracks their status with emojis, and sends smart notifications so reviewers know when it's their turn.

## Quick Start

Expand Down Expand Up @@ -37,7 +37,7 @@ Once installed, the bot needs to know which GitHub repositories to track. Contin

## Configuring Your Repositories

Ready-to-Review reads its configuration from a special GitHub repository in your organization. This lets you version-control your notification settings centrally.
reviewGOOSE:Slack reads its configuration from a special GitHub repository in your organization. This lets you version-control your notification settings centrally.

### Step 1: Create the .codeGROOVE Repository

Expand Down Expand Up @@ -110,7 +110,7 @@ channels:

```bash
git add slack.yaml
git commit -m "Configure Ready-to-Review Slack bot"
git commit -m "Configure reviewGOOSE:Slack"
git push
```

Expand Down Expand Up @@ -338,17 +338,17 @@ channels:

## Viewing Your Dashboard

Ready-to-Review provides two ways to view your PRs:
reviewGOOSE:Slack provides two ways to view your PRs:

### 1. Slack App Home

1. Click "Ready-to-Review" in your Slack sidebar
1. Click "reviewGOOSE" in your Slack sidebar
2. Select the "Home" tab
3. View incoming PRs (waiting on you) and outgoing PRs (waiting on others)

### 2. Web Dashboard

Visit [dash.ready-to-review.dev](https://dash.ready-to-review.dev/) for a comprehensive web view.
Visit [reviewgoose.dev](https://reviewgoose.dev/) for a comprehensive web view.

---

Expand All @@ -365,7 +365,7 @@ Visit [dash.ready-to-review.dev](https://dash.ready-to-review.dev/) for a compre

**Check channel permissions:**
- The bot needs permission to post in the channel
- Try inviting the bot: `/invite @Ready-to-Review`
- Try inviting the bot: `/invite @goose`

### Not receiving DMs

Expand Down Expand Up @@ -452,16 +452,16 @@ Before enabling:

- **Documentation:** [github.com/codeGROOVE-dev/slacker](https://github.com/codeGROOVE-dev/slacker)
- **Issues:** [GitHub Issues](https://github.com/codeGROOVE-dev/slacker/issues)
- **Support:** Contact your Ready-to-Review administrator
- **Support:** Contact your reviewGOOSE administrator

---

## What's Next?

Ready-to-Review is part of the codeGROOVE ecosystem of developer tools. Check out:
reviewGOOSE:Slack is part of the codeGROOVE ecosystem of developer tools. Check out:

- **[Sprinkler](https://github.com/codeGROOVE-dev/sprinkler)** - Real-time GitHub webhook hub
- **[Ready-to-Review Dashboard](https://dash.ready-to-review.dev/)** - Web-based PR dashboard
- **[reviewGOOSE:Desktop](https://github.com/codeGROOVE-dev/goose)** - Desktop app with honk notifications
- **[reviewGOOSE Dashboard](https://reviewgoose.dev/)** - Web-based PR dashboard
- **[codeGROOVE.dev](https://codegroove.dev/)** - Developer acceleration tools

Happy reviewing!
2 changes: 1 addition & 1 deletion pkg/bot/polling.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ func (c *Coordinator) checkDailyReports(ctx context.Context, org string, prs []g

// Create daily report sender and dashboard fetcher
sender := dailyreport.NewSender(c.stateStore, c.slack)
fetcher := home.NewFetcher(ghClient, c.stateStore, token, "ready-to-review[bot]")
fetcher := home.NewFetcher(ghClient, c.stateStore, token, "reviewgoose[bot]")

sentCount := 0
skippedCount := 0
Expand Down
12 changes: 6 additions & 6 deletions pkg/home/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (
)

// BuildBlocks creates Slack Block Kit UI for the home dashboard.
// Design matches dashboard at https://ready-to-review.dev - modern minimal with indigo accents.
// Design matches dashboard at https://reviewgoose.dev - modern minimal with indigo accents.
func BuildBlocks(dashboard *Dashboard, userTZ string) []slack.Block {
var blocks []slack.Block

// Header
blocks = append(blocks,
slack.NewHeaderBlock(
slack.NewTextBlockObject("plain_text", "🚀 Ready to Review", true, false),
slack.NewTextBlockObject("plain_text", "🚀 reviewGOOSE", true, false),
),
// Refresh button
slack.NewActionBlock(
Expand Down Expand Up @@ -63,7 +63,7 @@ func BuildBlocks(dashboard *Dashboard, userTZ string) []slack.Block {
esc := url.PathEscape(org)
orgLine := fmt.Sprintf("• %s [<%s|dashboard> | <%s|config>]",
org,
fmt.Sprintf("https://%s.ready-to-review.dev", esc),
fmt.Sprintf("https://reviewgoose.dev/orgs/%s", esc),
fmt.Sprintf("https://github.com/%s/.codeGROOVE/blob/main/slack.yaml", esc),
)
orgLines = append(orgLines, orgLine)
Expand Down Expand Up @@ -235,9 +235,9 @@ func BuildBlocksWithDebug(dashboard *Dashboard, userTZ string, mapping *usermapp
var blocks []slack.Block

// Header with GitHub username if available
headerText := "🚀 Ready to Review"
headerText := "🚀 reviewGOOSE"
if mapping != nil {
headerText = fmt.Sprintf("🚀 Ready to Review — @%s", mapping.GitHubUsername)
headerText = fmt.Sprintf("🚀 reviewGOOSE — @%s", mapping.GitHubUsername)
}

blocks = append(blocks,
Expand Down Expand Up @@ -283,7 +283,7 @@ func BuildBlocksWithDebug(dashboard *Dashboard, userTZ string, mapping *usermapp
esc := url.PathEscape(org)
orgLine := fmt.Sprintf("• %s [<%s|dashboard> | <%s|config>]",
org,
fmt.Sprintf("https://%s.ready-to-review.dev", esc),
fmt.Sprintf("https://reviewgoose.dev/orgs/%s", esc),
fmt.Sprintf("https://github.com/%s/.codeGROOVE/blob/main/slack.yaml", esc),
)
orgLines = append(orgLines, orgLine)
Expand Down
6 changes: 3 additions & 3 deletions pkg/home/ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ func TestBuildBlocks(t *testing.T) {
foundHeader := false
for _, block := range blocks {
if hb, ok := block.(*slack.HeaderBlock); ok {
if strings.Contains(hb.Text.Text, "Ready to Review") {
if strings.Contains(hb.Text.Text, "reviewGOOSE") {
foundHeader = true
}
}
}
if !foundHeader {
t.Error("expected header block with 'Ready to Review'")
t.Error("expected header block with 'reviewGOOSE'")
}

// Verify we don't have any PR section blocks (empty dashboard)
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestBuildBlocks(t *testing.T) {
foundLink := false
for _, block := range blocks {
if sb, ok := block.(*slack.SectionBlock); ok {
if sb.Text != nil && strings.Contains(sb.Text.Text, "ready-to-review.dev") {
if sb.Text != nil && strings.Contains(sb.Text.Text, "reviewgoose.dev") {
foundLink = true
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/slack/home_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (h *HomeHandler) tryHandleAppHomeOpened(ctx context.Context, teamID, slackU
ghClient,
h.stateStore,
githubClient.InstallationToken(ctx),
"ready-to-review[bot]",
"reviewgoose[bot]",
)

dashboard, err := fetcher.FetchDashboard(ctx, githubUsername, workspaceOrgs)
Expand Down
2 changes: 1 addition & 1 deletion pkg/slack/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Manager struct {
clients map[string]*Client // team_id -> client
metadata map[string]*WorkspaceMetadata
homeViewHandler func(ctx context.Context, teamID, userID string) error // Global home view handler
reportHandler func(ctx context.Context, teamID, userID string) error // Global report handler for /r2r report
reportHandler func(ctx context.Context, teamID, userID string) error // Global report handler for /goose report
}

// NewManager creates a new Slack client manager.
Expand Down
20 changes: 10 additions & 10 deletions pkg/slack/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func (*OAuthHandler) writeSuccessPage(writer http.ResponseWriter, teamName strin
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Installation Complete - Ready to Review</title>
<title>Installation Complete - reviewGOOSE:Slack</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Passion+One:wght@700&display=swap" rel="stylesheet">
Expand Down Expand Up @@ -333,10 +333,10 @@ func (*OAuthHandler) writeSuccessPage(writer http.ResponseWriter, teamName strin
<div class="success-container" role="status" aria-live="polite">
<span class="checkmark" role="img" aria-label="Success checkmark">✓</span>
<h1>Installation Complete!</h1>
<p>Ready to Review is now supercharging</p>
<p>reviewGOOSE:Slack is now active in</p>
<h2>%s</h2>
<p><span class="rocket" role="img" aria-label="Rocket">🚀</span>
Your dev team just got faster.
You'll know instantly when you're blocking a PR.
<span class="rocket" role="img" aria-label="Rocket">🚀</span></p>
<p class="cta">Next:
<a href="https://github.com/codeGROOVE-dev/slacker/blob/main/docs/SETUP.md#configuring-your-repositories"
Expand Down Expand Up @@ -415,7 +415,7 @@ func (*OAuthHandler) writeInstallPage(writer http.ResponseWriter, authURL string
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Install Ready to Review</title>
<title>Install reviewGOOSE:Slack</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Passion+One:wght@700&display=swap" rel="stylesheet">
Expand Down Expand Up @@ -509,13 +509,13 @@ func (*OAuthHandler) writeInstallPage(writer http.ResponseWriter, authURL string
</head>
<body>
<div class="install-container">
<h1>READY TO REVIEW</h1>
<p class="tagline">Supercharge your PR review workflow.</p>
<h1>reviewGOOSE:Slack</h1>
<p class="tagline">Know instantly when you're blocking a PR.</p>
<ul class="features">
<li>Real-time Slack notifications</li>
<li>Smart DM reminders</li>
<li>Multi-workspace support</li>
<li>Auto-discovery channels</li>
<li>Real-time PR status in Slack channels</li>
<li>Smart DMs when it's your turn to act</li>
<li>Daily digest of pending reviews</li>
<li>Works with reviewGOOSE:Desktop</li>
</ul>
<div class="button-container">
<a href="%s" class="add-to-slack">
Expand Down
2 changes: 1 addition & 1 deletion pkg/slack/oauth_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ func TestWriteInstallPage(t *testing.T) {
t.Error("Expected auth URL in output")
}

if !strings.Contains(body, "Install Ready to Review") || !strings.Contains(body, "Add to Slack") {
if !strings.Contains(body, "Install reviewGOOSE") || !strings.Contains(body, "Add to Slack") {
t.Error("Expected install button/text in output")
}
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/slack/report_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func NewReportHandler(
}
}

// HandleReportCommand handles the /r2r report slash command.
// HandleReportCommand handles the /goose report slash command.
// It generates and sends a daily report for the requesting user, bypassing time window and interval checks.
func (h *ReportHandler) HandleReportCommand(ctx context.Context, teamID, slackUserID string) error {
slog.Info("handling manual daily report request",
Expand Down Expand Up @@ -161,7 +161,7 @@ func (h *ReportHandler) HandleReportCommand(ctx context.Context, teamID, slackUs
slog.Error("failed to cast GitHub client", "org", foundOrg)
return fmt.Errorf("failed to cast GitHub client for org %s", foundOrg)
}
fetcher := home.NewFetcher(goGitHubClient, h.stateStore, token, "ready-to-review[bot]")
fetcher := home.NewFetcher(goGitHubClient, h.stateStore, token, "reviewgoose[bot]")

// Fetch dashboard for user across all orgs where they're a member
slog.Info("fetching dashboard for manual report",
Expand Down Expand Up @@ -190,7 +190,7 @@ func (h *ReportHandler) HandleReportCommand(ctx context.Context, teamID, slackUs
"slack_user", slackUserID,
"github_user", githubUsername)
_, _, err := slackClient.SendDirectMessage(ctx, slackUserID,
"You're all caught up! You have no pending PR reviews or outgoing PRs at the moment.")
"🎉 You're all caught up! No pending PR reviews or outgoing PRs right now.")
if err != nil {
slog.Error("failed to send empty report message",
"slack_user", slackUserID,
Expand Down
Loading
Loading