diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 9846e59..02f43ec 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -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 @@ -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) @@ -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 diff --git a/README.md b/README.md index d766939..440c54e 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/cmd/server/main.go b/cmd/server/main.go index cf22201..ec44831 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -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) diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 9faeec3..159b578 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -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 @@ -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 diff --git a/docs/SETUP.md b/docs/SETUP.md index 28cd56b..f626f17 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -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 @@ -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 @@ -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 ``` @@ -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. --- @@ -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 @@ -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! diff --git a/pkg/bot/polling.go b/pkg/bot/polling.go index f27c811..a85275f 100644 --- a/pkg/bot/polling.go +++ b/pkg/bot/polling.go @@ -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 diff --git a/pkg/home/ui.go b/pkg/home/ui.go index 947dce7..5e02f6a 100644 --- a/pkg/home/ui.go +++ b/pkg/home/ui.go @@ -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( @@ -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) @@ -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, @@ -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) diff --git a/pkg/home/ui_test.go b/pkg/home/ui_test.go index c5cd7eb..dc7e2fb 100644 --- a/pkg/home/ui_test.go +++ b/pkg/home/ui_test.go @@ -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) @@ -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 } } diff --git a/pkg/slack/home_handler.go b/pkg/slack/home_handler.go index 2c2b9a1..66d7d70 100644 --- a/pkg/slack/home_handler.go +++ b/pkg/slack/home_handler.go @@ -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) diff --git a/pkg/slack/manager.go b/pkg/slack/manager.go index 0212853..4abee62 100644 --- a/pkg/slack/manager.go +++ b/pkg/slack/manager.go @@ -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. diff --git a/pkg/slack/oauth.go b/pkg/slack/oauth.go index 838df0d..4411a9b 100644 --- a/pkg/slack/oauth.go +++ b/pkg/slack/oauth.go @@ -200,7 +200,7 @@ func (*OAuthHandler) writeSuccessPage(writer http.ResponseWriter, teamName strin - Installation Complete - Ready to Review + Installation Complete - reviewGOOSE:Slack @@ -333,10 +333,10 @@ func (*OAuthHandler) writeSuccessPage(writer http.ResponseWriter, teamName strin

Installation Complete!

-

Ready to Review is now supercharging

+

reviewGOOSE:Slack is now active in

%s

🚀 - Your dev team just got faster. + You'll know instantly when you're blocking a PR. 🚀

Next: - Install Ready to Review + Install reviewGOOSE:Slack @@ -509,13 +509,13 @@ func (*OAuthHandler) writeInstallPage(writer http.ResponseWriter, authURL string

-

READY TO REVIEW

-

Supercharge your PR review workflow.

+

reviewGOOSE:Slack

+

Know instantly when you're blocking a PR.

    -
  • Real-time Slack notifications
  • -
  • Smart DM reminders
  • -
  • Multi-workspace support
  • -
  • Auto-discovery channels
  • +
  • Real-time PR status in Slack channels
  • +
  • Smart DMs when it's your turn to act
  • +
  • Daily digest of pending reviews
  • +
  • Works with reviewGOOSE:Desktop
diff --git a/pkg/slack/oauth_handlers_test.go b/pkg/slack/oauth_handlers_test.go index d409977..01176d4 100644 --- a/pkg/slack/oauth_handlers_test.go +++ b/pkg/slack/oauth_handlers_test.go @@ -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") } } diff --git a/pkg/slack/report_handler.go b/pkg/slack/report_handler.go index 23e1751..f191e7b 100644 --- a/pkg/slack/report_handler.go +++ b/pkg/slack/report_handler.go @@ -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", @@ -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", @@ -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, diff --git a/pkg/slack/slack.go b/pkg/slack/slack.go index 1b30ce6..a6b74d5 100644 --- a/pkg/slack/slack.go +++ b/pkg/slack/slack.go @@ -71,7 +71,7 @@ type Client struct { cache *apiCache manager *Manager // Reference to manager for cache invalidation homeViewHandler func(ctx context.Context, teamID, userID string) error // Callback for app_home_opened events - reportHandler func(ctx context.Context, teamID, userID string) error // Callback for /r2r report slash command + reportHandler func(ctx context.Context, teamID, userID string) error // Callback for /goose report slash command retryDelay time.Duration // Base delay for retries (default: 2s, can be overridden for tests) } @@ -155,7 +155,7 @@ func (c *Client) SetHomeViewHandler(handler func(ctx context.Context, teamID, us c.homeViewHandler = handler } -// SetReportHandler registers a callback for /r2r report slash command. +// SetReportHandler registers a callback for /goose report slash command. func (c *Client) SetReportHandler(handler func(ctx context.Context, teamID, userID string) error) { c.reportHandlerMu.Lock() defer c.reportHandlerMu.Unlock() @@ -1102,8 +1102,8 @@ func (c *Client) SlashCommandHandler(writer http.ResponseWriter, r *http.Request // Handle different commands. var response string switch cmd.Command { - case "/r2r": - response = c.handleR2RCommand(r.Context(), &cmd) + case "/goose": + response = c.handleGooseCommand(r.Context(), &cmd) default: response = "Unknown command" } @@ -1118,8 +1118,8 @@ func (c *Client) SlashCommandHandler(writer http.ResponseWriter, r *http.Request } } -// handleR2RCommand handles the /r2r slash command. -func (c *Client) handleR2RCommand(ctx context.Context, cmd *slack.SlashCommand) string { +// handleGooseCommand handles the /goose slash command. +func (c *Client) handleGooseCommand(ctx context.Context, cmd *slack.SlashCommand) string { // Sanitize and validate input. text := strings.TrimSpace(cmd.Text) if len(text) > maxCommandInputLength { // Reasonable limit for command input. @@ -1128,7 +1128,7 @@ func (c *Client) handleR2RCommand(ctx context.Context, cmd *slack.SlashCommand) args := strings.Fields(text) if len(args) == 0 { - return "Usage: /r2r [dashboard|settings|report|help]" + return "Usage: /goose [dashboard|settings|report|help]" } // Validate command argument. @@ -1138,7 +1138,7 @@ func (c *Client) handleR2RCommand(ctx context.Context, cmd *slack.SlashCommand) // Note: In a full implementation, we'd send blocks here instead of plain text. // For now, return a link to the web dashboard. // SECURITY: URL encode user ID to prevent injection attacks - return fmt.Sprintf("View your dashboard at: https://dash.ready-to-review.dev/?user=%s\n"+ + return fmt.Sprintf("View your dashboard at: https://reviewgoose.dev/?user=%s\n"+ "Or use the Home tab in this app for the native Slack experience.", url.QueryEscape(cmd.UserID)) case "settings": return "Open the Home tab in this app to configure your notification preferences." @@ -1185,15 +1185,16 @@ func (c *Client) handleR2RCommand(ctx context.Context, cmd *slack.SlashCommand) // Return immediately to avoid timeout return "⏳ Generating your daily report..." case "help": - return "Ready to Review helps you stay on top of pull requests.\n" + - "Commands:\n" + - "• /r2r dashboard - View your PR dashboard\n" + - "• /r2r settings - Configure notification preferences\n" + - "• /r2r report - Generate and send your daily PR report now\n" + - "• /r2r help - Show this help message\n\n" + - "You can also visit the Home tab in this app for a full dashboard." + return "*reviewGOOSE:Slack* helps you stay on top of pull requests.\n\n" + + "*Commands:*\n" + + "• `/goose dashboard` - View your PR dashboard\n" + + "• `/goose settings` - Configure notification preferences\n" + + "• `/goose report` - Generate and send your daily PR report now\n" + + "• `/goose help` - Show this help message\n\n" + + "You can also visit the *Home* tab in this app for a full dashboard.\n" + + "Learn more at https://codegroove.dev/reviewgoose/" default: - return "Unknown subcommand. Try: /r2r help" + return "Unknown subcommand. Try: /goose help" } }