mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat(web): add Slack integration marketing page at /slack
- Create new /slack marketing page with SEO metadata - Add SlackHeroSection with @Roomote branding and dual CTAs - Add SlackValuePropsSection with 7 key value propositions - Add ThreadToFeatureWorkflow demonstrating the flagship workflow - Add SlackOnboardingSteps with 3-step setup guide - Add SlackCTASection for conversion - Update navigation to include Slack in Product dropdown (desktop + mobile) - Add SLACK_INTEGRATION_DOCS constant for documentation link Page follows existing patterns from /extension and /cloud pages.
This commit is contained in:
parent
e356d058e9
commit
973cbc27af
8 changed files with 570 additions and 1 deletions
69
apps/web-roo-code/src/app/slack/page.tsx
Normal file
69
apps/web-roo-code/src/app/slack/page.tsx
Normal file
|
|
@ -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 (
|
||||
<>
|
||||
<StructuredData />
|
||||
<SlackHeroSection />
|
||||
<SlackValuePropsSection />
|
||||
<ThreadToFeatureWorkflow />
|
||||
<SlackOnboardingSteps />
|
||||
<SlackCTASection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
36
apps/web-roo-code/src/app/slack/slack-cta-section.tsx
Normal file
36
apps/web-roo-code/src/app/slack/slack-cta-section.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { ArrowRight } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui"
|
||||
import { EXTERNAL_LINKS } from "@/lib/constants"
|
||||
|
||||
export function SlackCTASection() {
|
||||
return (
|
||||
<section className="py-24">
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-4xl rounded-3xl border border-border/50 bg-gradient-to-br from-violet-500/10 via-purple-500/5 to-blue-500/5 p-8 text-center shadow-2xl backdrop-blur-xl dark:border-white/10 sm:p-16">
|
||||
<h2 className="mb-6 text-3xl font-bold tracking-tight sm:text-4xl">
|
||||
Bring your AI team into Slack
|
||||
</h2>
|
||||
<p className="mx-auto mb-10 max-w-2xl text-lg text-muted-foreground">
|
||||
Start collaborating with agents where your team already works. Free to try.
|
||||
</p>
|
||||
<div className="flex flex-col justify-center space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0">
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-foreground text-background hover:bg-foreground/90 transition-all duration-300"
|
||||
asChild>
|
||||
<a
|
||||
href={EXTERNAL_LINKS.CLOUD_APP_SIGNUP}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center">
|
||||
Get Started
|
||||
<ArrowRight className="ml-2 h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
52
apps/web-roo-code/src/app/slack/slack-hero-section.tsx
Normal file
52
apps/web-roo-code/src/app/slack/slack-hero-section.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
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 (
|
||||
<section className="relative flex pt-32 pb-20 items-center overflow-hidden">
|
||||
<AnimatedBackground />
|
||||
<div className="container relative flex flex-col items-center h-full z-10 mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center max-w-4xl mx-auto mb-12">
|
||||
<h1 className="text-4xl font-bold tracking-tight mb-6 md:text-5xl lg:text-6xl">
|
||||
<span className="text-violet-500">@Roomote</span>: Your AI Team in Slack
|
||||
</h1>
|
||||
<p className="text-xl text-muted-foreground mb-4 max-w-2xl mx-auto">
|
||||
Summon agents to explain code, plan new features, or execute coding tasks without leaving Slack.
|
||||
</p>
|
||||
<p className="text-lg text-muted-foreground mb-8 max-w-2xl mx-auto">
|
||||
Mention @Roomote in any channel. Pick an agent and a repo. Get answers, plans, or a PR in the
|
||||
thread.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Button
|
||||
size="xl"
|
||||
className="bg-violet-600 hover:bg-violet-700 text-white transition-all duration-300 shadow-lg hover:shadow-violet-500/25"
|
||||
asChild>
|
||||
<a
|
||||
href={EXTERNAL_LINKS.CLOUD_APP_SIGNUP}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center">
|
||||
Get Started
|
||||
<ArrowRight className="ml-2 size-5" />
|
||||
</a>
|
||||
</Button>
|
||||
<Button variant="outline" size="xl" className="backdrop-blur-sm" asChild>
|
||||
<a
|
||||
href={EXTERNAL_LINKS.SLACK_INTEGRATION_DOCS}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center">
|
||||
Read the Docs
|
||||
<ExternalLink className="ml-2 size-4" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
76
apps/web-roo-code/src/app/slack/slack-onboarding-steps.tsx
Normal file
76
apps/web-roo-code/src/app/slack/slack-onboarding-steps.tsx
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { Settings, Link2, Hash, LucideIcon } from "lucide-react"
|
||||
|
||||
interface OnboardingStep {
|
||||
step: number
|
||||
icon: LucideIcon
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const onboardingSteps: OnboardingStep[] = [
|
||||
{
|
||||
step: 1,
|
||||
icon: Settings,
|
||||
title: "Connect your Slack workspace",
|
||||
description: "Go to your personal or org settings in the top right user menu",
|
||||
},
|
||||
{
|
||||
step: 2,
|
||||
icon: Link2,
|
||||
title: "Authorize the integration",
|
||||
description: "Click on 'Connect' and follow the OAuth process",
|
||||
},
|
||||
{
|
||||
step: 3,
|
||||
icon: Hash,
|
||||
title: "Add @Roomote to channels",
|
||||
description: "Add the @Roomote bot to the channels where you want it to be available",
|
||||
},
|
||||
]
|
||||
|
||||
export function SlackOnboardingSteps() {
|
||||
return (
|
||||
<section className="relative overflow-hidden border-t border-border py-32">
|
||||
<div className="container relative z-10 mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="absolute inset-y-0 left-1/2 h-full w-full max-w-[1200px] -translate-x-1/2 z-1">
|
||||
<div className="absolute left-1/2 top-1/2 h-[400px] w-full -translate-x-1/2 -translate-y-1/2 rounded-full bg-blue-500/10 dark:bg-blue-700/20 blur-[140px]" />
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mb-12 md:mb-24 max-w-5xl text-center">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold tracking-tight sm:text-5xl mb-4">Get started in 3 steps</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
||||
Connect your Slack workspace and start collaborating with agents in minutes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative mx-auto md:max-w-[1200px]">
|
||||
<ul className="grid grid-cols-1 place-items-center gap-6 md:grid-cols-3 lg:gap-8">
|
||||
{onboardingSteps.map((step) => {
|
||||
const Icon = step.icon
|
||||
return (
|
||||
<li
|
||||
key={step.step}
|
||||
className="relative h-full w-full border border-border rounded-2xl bg-background p-8 transition-all duration-300 hover:shadow-lg">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="bg-violet-100 dark:bg-violet-900/20 w-10 h-10 rounded-full flex items-center justify-center">
|
||||
<span className="text-violet-600 dark:text-violet-400 font-bold">
|
||||
{step.step}
|
||||
</span>
|
||||
</div>
|
||||
<Icon className="size-5 text-foreground/60" />
|
||||
</div>
|
||||
<h3 className="mb-3 text-xl font-semibold text-foreground">{step.title}</h3>
|
||||
<div className="leading-relaxed font-light text-muted-foreground">
|
||||
{step.description}
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
import { MessageSquare, Brain, GitBranch, Users, GraduationCap, Share2, Shield, LucideIcon } from "lucide-react"
|
||||
|
||||
interface ValueProp {
|
||||
icon: LucideIcon
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const valueProps: ValueProp[] = [
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "From discussion to shipped 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: "The agent knows the thread",
|
||||
description:
|
||||
"@Roomote reads the conversation before responding. Ask 'why is this happening?' after a team discussion and it understands.",
|
||||
},
|
||||
{
|
||||
icon: GitBranch,
|
||||
title: "Chain agents for complex work",
|
||||
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: "Non-technical team members can investigate",
|
||||
description:
|
||||
"PMs, CSMs, and support can ask @Roomote to explain code or investigate issues. Engineering gets pulled in only when truly needed.",
|
||||
},
|
||||
{
|
||||
icon: GraduationCap,
|
||||
title: "Team learning, built in",
|
||||
description: "Public channel mentions show everyone how to leverage agents. Learn by watching.",
|
||||
},
|
||||
{
|
||||
icon: Share2,
|
||||
title: "One platform, multiple surfaces",
|
||||
description:
|
||||
"The same agents that work in your IDE and review your PRs are available in Slack. Different surfaces, same quality.",
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Safe by design",
|
||||
description: "Agents never touch main/master directly. They produce branches and PRs. Humans approve.",
|
||||
},
|
||||
]
|
||||
|
||||
export function SlackValuePropsSection() {
|
||||
return (
|
||||
<section className="py-24 bg-muted/30">
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative">
|
||||
<div className="absolute inset-y-0 left-1/2 h-full w-full max-w-[1200px] -translate-x-1/2 z-1">
|
||||
<div className="absolute left-1/2 top-1/2 h-[800px] w-full -translate-x-1/2 -translate-y-1/2 rounded-full bg-violet-500/10 dark:bg-violet-700/20 blur-[140px]" />
|
||||
</div>
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl mb-4">
|
||||
Why teams love working with @Roomote
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
|
||||
Collaboration where it already happens, with AI that understands context.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto relative">
|
||||
{valueProps.map((prop, index) => {
|
||||
const Icon = prop.icon
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-background p-8 rounded-2xl border border-border hover:shadow-lg transition-all duration-300">
|
||||
<div className="bg-violet-100 dark:bg-violet-900/20 w-12 h-12 rounded-lg flex items-center justify-center mb-6">
|
||||
<Icon className="size-6 text-violet-600 dark:text-violet-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold mb-3">{prop.title}</h3>
|
||||
<p className="text-muted-foreground leading-relaxed">{prop.description}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
237
apps/web-roo-code/src/app/slack/thread-to-feature-workflow.tsx
Normal file
237
apps/web-roo-code/src/app/slack/thread-to-feature-workflow.tsx
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
"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: "Human oversight at every step. Agents produce artifacts; humans 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 (
|
||||
<div className="flex gap-3 py-2">
|
||||
<div
|
||||
className={`w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 text-sm font-semibold ${
|
||||
message.isBot
|
||||
? "bg-violet-100 dark:bg-violet-900/40 text-violet-600 dark:text-violet-400"
|
||||
: "bg-muted text-muted-foreground"
|
||||
}`}>
|
||||
{message.avatar}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-baseline gap-2 mb-0.5">
|
||||
<span className={`font-semibold text-sm ${message.isBot ? "text-violet-600 dark:text-violet-400" : ""}`}>
|
||||
{message.user}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">{message.role}</span>
|
||||
</div>
|
||||
<p className="text-sm text-foreground/90 leading-relaxed">{message.message}</p>
|
||||
{message.reactions && message.reactions.length > 0 && (
|
||||
<div className="flex gap-1 mt-1.5">
|
||||
{message.reactions.map((reaction, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className="inline-flex items-center gap-1 px-2 py-0.5 bg-muted rounded-full text-xs">
|
||||
{reaction}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function WorkflowStepCard({ step }: { step: WorkflowStep }) {
|
||||
const stepIcons = [Map, MessageCircle, Code, GitPullRequest]
|
||||
const Icon = stepIcons[step.step - 1] || Map
|
||||
|
||||
return (
|
||||
<div className="bg-background rounded-2xl border border-border overflow-hidden hover:shadow-lg transition-all duration-300">
|
||||
{/* Step Header */}
|
||||
<div className="p-6 border-b border-border bg-muted/30">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="bg-violet-100 dark:bg-violet-900/20 w-8 h-8 rounded-full flex items-center justify-center">
|
||||
<span className="text-violet-600 dark:text-violet-400 font-bold text-sm">{step.step}</span>
|
||||
</div>
|
||||
<Icon className="size-5 text-violet-600 dark:text-violet-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-semibold mb-1">{step.title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{step.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Slack Thread Mockup */}
|
||||
<div className="p-4 bg-background">
|
||||
<div className="space-y-1">
|
||||
{step.messages.map((message, i) => (
|
||||
<SlackMessageComponent key={i} message={message} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Result */}
|
||||
<div className="p-4 border-t border-border bg-violet-50/50 dark:bg-violet-900/10">
|
||||
<div className="flex items-start gap-2 text-sm">
|
||||
<CornerDownRight className="size-4 text-violet-600 dark:text-violet-400 mt-0.5 flex-shrink-0" />
|
||||
<span className="text-violet-700 dark:text-violet-300 font-medium">{step.result}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function ThreadToFeatureWorkflow() {
|
||||
return (
|
||||
<section className="py-24 bg-background">
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-violet-100 dark:bg-violet-900/30 text-violet-700 dark:text-violet-300 text-sm font-medium mb-4">
|
||||
<Eye className="size-4" />
|
||||
Featured Workflow
|
||||
</div>
|
||||
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl mb-4">
|
||||
From Discussion to Shipped Feature
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
|
||||
The complete workflow that makes Slack the ideal surface for agent collaboration. Discussion
|
||||
→ spec → code → PR, all in one thread.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 max-w-6xl mx-auto">
|
||||
{workflowSteps.map((step) => (
|
||||
<WorkflowStepCard key={step.step} step={step} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-12 text-center">
|
||||
<p className="text-muted-foreground max-w-2xl mx-auto">
|
||||
<strong className="text-foreground">No context switch required.</strong> Everyone sees the
|
||||
workflow in public channels. Multi-agent handoffs from Planner to Coder. Human oversight at
|
||||
every step.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -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) {
|
|||
<Cloud className="size-3 inline mr-2 -mt-0.5" />
|
||||
Roo Code Cloud
|
||||
</Link>
|
||||
<Link
|
||||
href="/slack"
|
||||
className="block px-4 py-2 text-sm transition-colors hover:bg-accent hover:text-foreground">
|
||||
<Slack className="size-3 inline mr-2 -mt-0.5" />
|
||||
Roo Code for Slack
|
||||
</Link>
|
||||
<Link
|
||||
href="/provider"
|
||||
className="block px-4 py-2 text-sm transition-colors hover:bg-accent hover:text-foreground">
|
||||
|
|
@ -190,6 +196,12 @@ export function NavBar({ stars, downloads }: NavBarProps) {
|
|||
onClick={() => setIsMenuOpen(false)}>
|
||||
Roo Code Cloud
|
||||
</Link>
|
||||
<Link
|
||||
href="/slack"
|
||||
className="block w-full p-5 py-3 text-left text-foreground active:opacity-50"
|
||||
onClick={() => setIsMenuOpen(false)}>
|
||||
Roo Code for Slack
|
||||
</Link>
|
||||
<Link
|
||||
href="/provider"
|
||||
className="block w-full p-5 py-3 text-left text-foreground active:opacity-50"
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export const EXTERNAL_LINKS = {
|
|||
CLOUD_APP_SIGNUP_HOME: "https://app.roocode.com/sign-up?redirect_url=/cloud-agents/setup",
|
||||
CLOUD_APP_SIGNUP_PRO: "https://app.roocode.com/sign-up?redirect_url=/cloud-agents/setup",
|
||||
SUPPORT: "mailto:support@roocode.com",
|
||||
SLACK_INTEGRATION_DOCS: "https://docs.roocode.com/roo-code-cloud/slack-integration",
|
||||
}
|
||||
|
||||
export const INTERNAL_LINKS = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue