diff --git a/apps/web-roo-code/src/app/slack/page.tsx b/apps/web-roo-code/src/app/slack/page.tsx new file mode 100644 index 00000000000..84437d995b0 --- /dev/null +++ b/apps/web-roo-code/src/app/slack/page.tsx @@ -0,0 +1,69 @@ +import type { Metadata } from "next" + +import { StructuredData } from "@/components/structured-data" +import { SEO } from "@/lib/seo" +import { ogImageUrl } from "@/lib/og" + +import { SlackHeroSection } from "./slack-hero-section" +import { SlackValuePropsSection } from "./slack-value-props-section" +import { ThreadToFeatureWorkflow } from "./thread-to-feature-workflow" +import { SlackOnboardingSteps } from "./slack-onboarding-steps" +import { SlackCTASection } from "./slack-cta-section" + +const TITLE = "Roo Code for Slack" +const DESCRIPTION = + "Summon agents to explain code, plan new features, or execute coding tasks without leaving Slack. Your AI team in your team's workspace." +const OG_DESCRIPTION = "@Roomote: Your AI Team in Slack" +const PATH = "/slack" + +export const metadata: Metadata = { + title: TITLE, + description: DESCRIPTION, + alternates: { + canonical: `${SEO.url}${PATH}`, + }, + openGraph: { + title: TITLE, + description: DESCRIPTION, + url: `${SEO.url}${PATH}`, + siteName: SEO.name, + images: [ + { + url: ogImageUrl(TITLE, OG_DESCRIPTION), + width: 1200, + height: 630, + alt: TITLE, + }, + ], + locale: SEO.locale, + type: "website", + }, + twitter: { + card: SEO.twitterCard, + title: TITLE, + description: DESCRIPTION, + images: [ogImageUrl(TITLE, OG_DESCRIPTION)], + }, + keywords: [ + ...SEO.keywords, + "Slack integration", + "team collaboration", + "Slack bot", + "AI Slack assistant", + "@Roomote", + "Slack agents", + ], +} + +export default function SlackPage() { + return ( + <> + + + + + + + + ) +} diff --git a/apps/web-roo-code/src/app/slack/slack-cta-section.tsx b/apps/web-roo-code/src/app/slack/slack-cta-section.tsx new file mode 100644 index 00000000000..e782bb092a4 --- /dev/null +++ b/apps/web-roo-code/src/app/slack/slack-cta-section.tsx @@ -0,0 +1,36 @@ +import { ArrowRight } from "lucide-react" + +import { Button } from "@/components/ui" +import { EXTERNAL_LINKS } from "@/lib/constants" + +export function SlackCTASection() { + return ( +
+
+
+

+ Start using Roo Code in Slack +

+

+ Start with a free 14-day Team Plan trial. +

+ +
+
+
+ ) +} diff --git a/apps/web-roo-code/src/app/slack/slack-hero-section.tsx b/apps/web-roo-code/src/app/slack/slack-hero-section.tsx new file mode 100644 index 00000000000..7111cb01761 --- /dev/null +++ b/apps/web-roo-code/src/app/slack/slack-hero-section.tsx @@ -0,0 +1,48 @@ +import { ArrowRight, ExternalLink } from "lucide-react" + +import { Button } from "@/components/ui" +import { AnimatedBackground } from "@/components/homepage" +import { EXTERNAL_LINKS } from "@/lib/constants" + +export function SlackHeroSection() { + return ( +
+ +
+
+

+ @Roomote: Your AI Team in Slack +

+

+ Summon agents to explain code, plan new features, or execute coding tasks without leaving Slack. +

+ +
+
+
+ ) +} diff --git a/apps/web-roo-code/src/app/slack/slack-onboarding-steps.tsx b/apps/web-roo-code/src/app/slack/slack-onboarding-steps.tsx new file mode 100644 index 00000000000..9b2c6229e0a --- /dev/null +++ b/apps/web-roo-code/src/app/slack/slack-onboarding-steps.tsx @@ -0,0 +1,104 @@ +import { Settings, Link2, Hash, CreditCard, LucideIcon } from "lucide-react" + +import { EXTERNAL_LINKS } from "@/lib/constants" + +interface OnboardingStep { + step: number + icon: LucideIcon + title: string + description: string + link?: { + href: string + text: string + } +} + +const onboardingSteps: OnboardingStep[] = [ + { + step: 1, + icon: CreditCard, + title: "Get a Team Plan", + description: "Slack requires a Team Plan.", + link: { + href: EXTERNAL_LINKS.CLOUD_APP_TEAM_TRIAL, + text: "Start a free 14-day trial", + }, + }, + { + step: 2, + icon: Settings, + title: "Connect Slack", + description: 'Go to Organization Settings and click "Connect" under Integrations.', + }, + { + step: 3, + icon: Link2, + title: "Authorize", + description: "Complete the OAuth flow to connect your workspace.", + }, + { + step: 4, + icon: Hash, + title: "Add to channels", + description: "Add @Roomote to the channels where you want it available.", + }, +] + +export function SlackOnboardingSteps() { + return ( +
+
+
+
+
+ +
+
+

Get started in minutes

+

+ Connect your Slack workspace and start working with AI agents. +

+
+
+ +
+
    + {onboardingSteps.map((step) => { + const Icon = step.icon + return ( +
  • +
    +
    + + {step.step} + +
    + +
    +

    {step.title}

    +
    + {step.description} + {step.link && ( + <> + {" "} + + {step.link.text} + + + )} +
    +
  • + ) + })} +
+
+
+
+ ) +} diff --git a/apps/web-roo-code/src/app/slack/slack-value-props-section.tsx b/apps/web-roo-code/src/app/slack/slack-value-props-section.tsx new file mode 100644 index 00000000000..ea2849b2da6 --- /dev/null +++ b/apps/web-roo-code/src/app/slack/slack-value-props-section.tsx @@ -0,0 +1,80 @@ +import { MessageSquare, Brain, GitBranch, Users, GraduationCap, Shield, LucideIcon } from "lucide-react" + +interface ValueProp { + icon: LucideIcon + title: string + description: string +} + +const valueProps: ValueProp[] = [ + { + icon: MessageSquare, + title: "Discussion to feature.", + description: + "Your team discusses a feature in Slack. @Roomote turns the discussion into a plan. Then builds it. All without leaving the conversation.", + }, + { + icon: Brain, + title: "Full thread context.", + description: + "@Roomote reads the conversation before responding. Ask 'why is this happening?' after a team discussion and it understands.", + }, + { + icon: GitBranch, + title: "Chain agents together.", + description: + "Start with a Planner to spec it out. Then call the Coder to build it. Multi-step workflows, one Slack thread.", + }, + { + icon: Users, + title: "Anyone can contribute.", + description: + "PMs, CSMs, and Sales can ask @Roomote to explain code, prototype features, or build internal tools. No engineering bottleneck.", + }, + { + icon: GraduationCap, + title: "Team learning, built in.", + description: "Public channel mentions show everyone how to leverage agents. Learn by watching.", + }, + { + icon: Shield, + title: "Safe by design.", + description: "Agents never touch main/master directly. They produce branches and PRs. You approve.", + }, +] + +export function SlackValuePropsSection() { + return ( +
+
+
+
+
+
+

+ Why teams love working with @Roomote +

+

+ AI agents that understand context, chain together for complex work, and keep you in control. +

+
+
+ {valueProps.map((prop, index) => { + const Icon = prop.icon + return ( +
+
+ +
+

{prop.title}

+

{prop.description}

+
+ ) + })} +
+
+
+ ) +} diff --git a/apps/web-roo-code/src/app/slack/thread-to-feature-workflow.tsx b/apps/web-roo-code/src/app/slack/thread-to-feature-workflow.tsx new file mode 100644 index 00000000000..c38d3af22b5 --- /dev/null +++ b/apps/web-roo-code/src/app/slack/thread-to-feature-workflow.tsx @@ -0,0 +1,238 @@ +"use client" + +import { Map, MessageCircle, Code, GitPullRequest, Eye, CornerDownRight } from "lucide-react" + +interface SlackMessage { + user: string + role: string + avatar: string + message: string + isBot?: boolean + reactions?: string[] +} + +interface WorkflowStep { + step: number + title: string + description: string + result: string + messages: SlackMessage[] +} + +const workflowSteps: WorkflowStep[] = [ + { + step: 1, + title: "Turn the discussion into a plan", + description: "Capture complex discussions and transform them into structured specs", + result: "Planner agent reads the thread and returns a structured spec", + messages: [ + { + user: "Sarah", + role: "PM", + avatar: "S", + message: "This is getting complex. Let's not lose this.", + }, + { + user: "Sarah", + role: "PM", + avatar: "S", + message: + "@Roomote plan out a dark mode feature based on our discussion. Include the toggle, persistence, and system preference detection.", + }, + { + user: "Roomote", + role: "Planner Agent", + avatar: "R", + message: "I'll analyze the thread and create a structured plan...", + isBot: true, + reactions: ["👀"], + }, + ], + }, + { + step: 2, + title: "Refine the plan in the thread", + description: "Collaborate with your team to review and improve the spec", + result: "The team iterates on the plan without leaving the conversation", + messages: [ + { + user: "Alex", + role: "Designer", + avatar: "A", + message: "Can we add a system preference auto-detect option?", + }, + { + user: "Sarah", + role: "PM", + avatar: "S", + message: "@Roomote update the plan to include auto-detect from system preferences", + }, + { + user: "Roomote", + role: "Planner Agent", + avatar: "R", + message: "Updated the plan. Added system preference detection as the default behavior...", + isBot: true, + }, + ], + }, + { + step: 3, + title: "Build the plan", + description: "Hand off the refined spec to the Coder agent", + result: "Coder agent creates a branch and opens a PR", + messages: [ + { + user: "Mike", + role: "Engineer", + avatar: "M", + message: "This looks good. Let's build it.", + }, + { + user: "Mike", + role: "Engineer", + avatar: "M", + message: "@Roomote implement this plan in the frontend-web repo.", + }, + { + user: "Roomote", + role: "Coder Agent", + avatar: "R", + message: "Building the dark mode feature. I'll create a PR when ready...", + isBot: true, + reactions: ["👀"], + }, + ], + }, + { + step: 4, + title: "Review and ship", + description: "Review the PR and merge when ready", + result: "You stay in control. Agents produce artifacts; you decide what ships.", + messages: [ + { + user: "Roomote", + role: "Coder Agent", + avatar: "R", + message: "PR ready for review: feat: Add dark mode with system preference detection #247", + isBot: true, + }, + { + user: "Mike", + role: "Engineer", + avatar: "M", + message: "Reviewing now. LGTM! Merging.", + }, + ], + }, +] + +function SlackMessageComponent({ message }: { message: SlackMessage }) { + return ( +
+
+ {message.avatar} +
+
+
+ + {message.user} + + {message.role} +
+

{message.message}

+ {message.reactions && message.reactions.length > 0 && ( +
+ {message.reactions.map((reaction, i) => ( + + {reaction} + + ))} +
+ )} +
+
+ ) +} + +function WorkflowStepCard({ step }: { step: WorkflowStep }) { + const stepIcons = [Map, MessageCircle, Code, GitPullRequest] + const Icon = stepIcons[step.step - 1] || Map + + return ( +
+ {/* Step Header */} +
+
+
+ {step.step} +
+ +
+

{step.title}

+

{step.description}

+
+ + {/* Slack Thread Mockup */} +
+
+ {step.messages.map((message, i) => ( + + ))} +
+
+ + {/* Result */} +
+
+ + {step.result} +
+
+
+ ) +} + +export function ThreadToFeatureWorkflow() { + return ( +
+
+
+
+ + Featured Workflow +
+

+ From Discussion to Shipped Feature +

+

+ The complete workflow that makes Slack the ideal surface for agent collaboration. Discussion + → spec → code → PR, all in one thread. +

+
+ +
+ {workflowSteps.map((step) => ( + + ))} +
+ +
+

+ No context switch required. Everyone sees the + workflow in public channels. Multi-agent handoffs from Planner to Coder. You stay in control at + every step. +

+
+
+
+ ) +} diff --git a/apps/web-roo-code/src/components/chromes/nav-bar.tsx b/apps/web-roo-code/src/components/chromes/nav-bar.tsx index ba197004948..023114c2d3f 100644 --- a/apps/web-roo-code/src/components/chromes/nav-bar.tsx +++ b/apps/web-roo-code/src/components/chromes/nav-bar.tsx @@ -13,7 +13,7 @@ import { EXTERNAL_LINKS } from "@/lib/constants" import { useLogoSrc } from "@/lib/hooks/use-logo-src" import { ScrollButton } from "@/components/ui" import ThemeToggle from "@/components/chromes/theme-toggle" -import { Brain, ChevronDown, Cloud, Puzzle, X } from "lucide-react" +import { Brain, ChevronDown, Cloud, Puzzle, Slack, X } from "lucide-react" interface NavBarProps { stars: string | null @@ -54,6 +54,12 @@ export function NavBar({ stars, downloads }: NavBarProps) { Roo Code Cloud + + + Roo Code for Slack + @@ -190,6 +196,12 @@ export function NavBar({ stars, downloads }: NavBarProps) { onClick={() => setIsMenuOpen(false)}> Roo Code Cloud + setIsMenuOpen(false)}> + Roo Code for Slack +