Skip to content

Commit 32d7e6f

Browse files
authored
Add an announcement for Supernova (RooCodeInc#8197)
* Add an announcement for Supernova * Remove duplicate keys
1 parent 1533efc commit 32d7e6f

File tree

25 files changed

+219
-398
lines changed

25 files changed

+219
-398
lines changed

packages/cloud/src/CloudService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,9 @@ export class CloudService extends EventEmitter<CloudServiceEvents> implements Di
170170

171171
// AuthService
172172

173-
public async login(): Promise<void> {
173+
public async login(landingPageSlug?: string): Promise<void> {
174174
this.ensureInitialized()
175-
return this.authService!.login()
175+
return this.authService!.login(landingPageSlug)
176176
}
177177

178178
public async logout(): Promise<void> {

packages/cloud/src/WebAuthService.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,10 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
248248
*
249249
* This method initiates the authentication flow by generating a state parameter
250250
* and opening the browser to the authorization URL.
251+
*
252+
* @param landingPageSlug Optional slug of a specific landing page (e.g., "supernova", "special-offer", etc.)
251253
*/
252-
public async login(): Promise<void> {
254+
public async login(landingPageSlug?: string): Promise<void> {
253255
try {
254256
const vscode = await importVscode()
255257

@@ -267,11 +269,17 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
267269
state,
268270
auth_redirect: `${vscode.env.uriScheme}://${publisher}.${name}`,
269271
})
270-
const url = `${getRooCodeApiUrl()}/extension/sign-in?${params.toString()}`
272+
273+
// Use landing page URL if slug is provided, otherwise use default sign-in URL
274+
const url = landingPageSlug
275+
? `${getRooCodeApiUrl()}/l/${landingPageSlug}?${params.toString()}`
276+
: `${getRooCodeApiUrl()}/extension/sign-in?${params.toString()}`
277+
271278
await vscode.env.openExternal(vscode.Uri.parse(url))
272279
} catch (error) {
273-
this.log(`[auth] Error initiating Roo Code Cloud auth: ${error}`)
274-
throw new Error(`Failed to initiate Roo Code Cloud authentication: ${error}`)
280+
const context = landingPageSlug ? ` (landing page: ${landingPageSlug})` : ""
281+
this.log(`[auth] Error initiating Roo Code Cloud auth${context}: ${error}`)
282+
throw new Error(`Failed to initiate Roo Code Cloud authentication${context}: ${error}`)
275283
}
276284
}
277285

packages/types/src/cloud.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export interface AuthService extends EventEmitter<AuthServiceEvents> {
239239
broadcast(): void
240240

241241
// Authentication methods
242-
login(): Promise<void>
242+
login(landingPageSlug?: string): Promise<void>
243243
logout(): Promise<void>
244244
handleCallback(code: string | null, state: string | null, organizationId?: string | null): Promise<void>
245245

src/core/webview/ClineProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export class ClineProvider
143143

144144
public isViewLaunched = false
145145
public settingsImportedAt?: number
146-
public readonly latestAnnouncementId = "sep-2025-roo-code-cloud" // Roo Code Cloud announcement
146+
public readonly latestAnnouncementId = "sep-2025-code-supernova" // Code Supernova stealth model announcement
147147
public readonly providerSettingsManager: ProviderSettingsManager
148148
public readonly customModesManager: CustomModesManager
149149

src/core/webview/webviewMessageHandler.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,17 @@ export const webviewMessageHandler = async (
23022302

23032303
break
23042304
}
2305+
case "cloudLandingPageSignIn": {
2306+
try {
2307+
const landingPageSlug = message.text || "supernova"
2308+
TelemetryService.instance.captureEvent(TelemetryEventName.AUTHENTICATION_INITIATED)
2309+
await CloudService.instance.login(landingPageSlug)
2310+
} catch (error) {
2311+
provider.log(`CloudService#login failed: ${error}`)
2312+
vscode.window.showErrorMessage("Sign in failed.")
2313+
}
2314+
break
2315+
}
23052316
case "rooCloudSignOut": {
23062317
try {
23072318
await CloudService.instance.logout()

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export interface WebviewMessage {
180180
| "hasOpenedModeSelector"
181181
| "cloudButtonClicked"
182182
| "rooCloudSignIn"
183+
| "cloudLandingPageSignIn"
183184
| "rooCloudSignOut"
184185
| "rooCloudManualUrl"
185186
| "condenseTaskContextRequest"

webview-ui/src/components/chat/Announcement.tsx

Lines changed: 47 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ import { Package } from "@roo/package"
66
import { useAppTranslation } from "@src/i18n/TranslationContext"
77
import { useExtensionState } from "@src/context/ExtensionStateContext"
88
import { vscode } from "@src/utils/vscode"
9-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@src/components/ui"
9+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@src/components/ui"
1010
import { Button } from "@src/components/ui"
1111

12-
// Define the production URL constant locally to avoid importing from cloud package in webview
13-
const PRODUCTION_ROO_CODE_API_URL = "https://app.roocode.com"
14-
1512
interface AnnouncementProps {
1613
hideAnnouncement: () => void
1714
}
@@ -28,8 +25,7 @@ interface AnnouncementProps {
2825
const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {
2926
const { t } = useAppTranslation()
3027
const [open, setOpen] = useState(true)
31-
const { cloudApiUrl } = useExtensionState()
32-
const cloudUrl = cloudApiUrl || PRODUCTION_ROO_CODE_API_URL
28+
const { cloudIsAuthenticated } = useExtensionState()
3329

3430
return (
3531
<Dialog
@@ -44,71 +40,57 @@ const Announcement = ({ hideAnnouncement }: AnnouncementProps) => {
4440
<DialogContent className="max-w-96">
4541
<DialogHeader>
4642
<DialogTitle>{t("chat:announcement.title", { version: Package.version })}</DialogTitle>
47-
<DialogDescription>
48-
<Trans
49-
i18nKey="chat:announcement.description"
50-
components={{
51-
bold: <b />,
52-
}}
53-
/>
54-
</DialogDescription>
5543
</DialogHeader>
5644
<div>
57-
<ul className="space-y-2">
58-
<li>
59-
{" "}
60-
<Trans
61-
i18nKey="chat:announcement.feature1"
62-
components={{
63-
bold: <b />,
64-
}}
65-
/>
66-
</li>
67-
<li>
68-
{" "}
69-
<Trans
70-
i18nKey="chat:announcement.feature2"
71-
components={{
72-
bold: <b />,
73-
}}
74-
/>
75-
</li>
76-
</ul>
77-
78-
<div className="mt-4">
45+
<div className="mb-3">
7946
<Trans
80-
i18nKey="chat:announcement.learnMore"
47+
i18nKey="chat:announcement.stealthModel.feature"
8148
components={{
82-
learnMoreLink: (
83-
<VSCodeLink
84-
href="https://docs.roocode.com/update-notes/v3.28.0#task-sync--roomote-control"
85-
onClick={(e) => {
86-
e.preventDefault()
87-
window.postMessage(
88-
{
89-
type: "action",
90-
action: "openExternal",
91-
data: {
92-
url: "https://docs.roocode.com/update-notes/v3.28.0#task-sync--roomote-control",
93-
},
94-
},
95-
"*",
96-
)
97-
}}
98-
/>
99-
),
49+
bold: <b />,
10050
}}
10151
/>
10252
</div>
10353

54+
<p className="mt-3 text-sm text-vscode-descriptionForeground">
55+
{t("chat:announcement.stealthModel.note")}
56+
</p>
57+
10458
<div className="mt-4">
105-
<Button
106-
onClick={() => {
107-
vscode.postMessage({ type: "openExternal", url: cloudUrl })
108-
}}
109-
className="w-full">
110-
{t("chat:announcement.visitCloudButton")}
111-
</Button>
59+
{!cloudIsAuthenticated ? (
60+
<Button
61+
onClick={() => {
62+
vscode.postMessage({
63+
type: "cloudLandingPageSignIn",
64+
text: "supernova",
65+
})
66+
}}
67+
className="w-full">
68+
{t("chat:announcement.stealthModel.connectButton")}
69+
</Button>
70+
) : (
71+
<>
72+
<p className="mb-3">
73+
<Trans
74+
i18nKey="chat:announcement.stealthModel.selectModel"
75+
components={{
76+
code: <code />,
77+
}}
78+
/>
79+
</p>
80+
<Button
81+
onClick={() => {
82+
setOpen(false)
83+
hideAnnouncement()
84+
vscode.postMessage({
85+
type: "switchTab",
86+
tab: "settings",
87+
})
88+
}}
89+
className="w-full">
90+
{t("chat:announcement.stealthModel.goToSettingsButton")}
91+
</Button>
92+
</>
93+
)}
11294
</div>
11395

11496
<div className="mt-4 text-sm text-center">
@@ -132,7 +114,7 @@ const XLink = () => (
132114
href="https://x.com/roo_code"
133115
onClick={(e) => {
134116
e.preventDefault()
135-
window.postMessage({ type: "action", action: "openExternal", data: { url: "https://x.com/roo_code" } }, "*")
117+
vscode.postMessage({ type: "openExternal", url: "https://x.com/roo_code" })
136118
}}>
137119
X
138120
</VSCodeLink>
@@ -143,10 +125,7 @@ const DiscordLink = () => (
143125
href="https://discord.gg/rCQcvT7Fnt"
144126
onClick={(e) => {
145127
e.preventDefault()
146-
window.postMessage(
147-
{ type: "action", action: "openExternal", data: { url: "https://discord.gg/rCQcvT7Fnt" } },
148-
"*",
149-
)
128+
vscode.postMessage({ type: "openExternal", url: "https://discord.gg/rCQcvT7Fnt" })
150129
}}>
151130
Discord
152131
</VSCodeLink>
@@ -157,10 +136,7 @@ const RedditLink = () => (
157136
href="https://www.reddit.com/r/RooCode/"
158137
onClick={(e) => {
159138
e.preventDefault()
160-
window.postMessage(
161-
{ type: "action", action: "openExternal", data: { url: "https://www.reddit.com/r/RooCode/" } },
162-
"*",
163-
)
139+
vscode.postMessage({ type: "openExternal", url: "https://www.reddit.com/r/RooCode/" })
164140
}}>
165141
r/RooCode
166142
</VSCodeLink>

webview-ui/src/i18n/locales/ca/chat.json

Lines changed: 8 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/chat.json

Lines changed: 8 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/chat.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,14 @@
291291
},
292292
"announcement": {
293293
"title": "🎉 Roo Code {{version}} Released",
294-
"description": "Introducing <bold>Roo Code Cloud:</bold> Bringing the power of Roo beyond the IDE",
295-
"feature1": "<bold>Track task progress from anywhere (Free):</bold> Get real-time updates on long-running tasks without being stuck in your IDE",
296-
"feature2": "<bold>Control the Roo Extension remotely (Pro):</bold> Start, stop, and interact with tasks from a chat-based browser interface.",
297-
"learnMore": "Ready to take control? Learn more <learnMoreLink>here</learnMoreLink>.",
298-
"visitCloudButton": "Visit Roo Code Cloud",
299-
"socialLinks": "Join us on <xLink>X</xLink>, <discordLink>Discord</discordLink>, or <redditLink>r/RooCode</redditLink>"
294+
"stealthModel": {
295+
"feature": "<bold>Limited-time FREE stealth model</bold> - Code Supernova: A versatile agentic coding model that supports image inputs, accessible through Roo Code Cloud.",
296+
"note": "(Note: prompts and completions are logged by the model creator and used to improve the model)",
297+
"connectButton": "Connect to Roo Code Cloud",
298+
"selectModel": "Select <code>roo/code-supernova</code> from the Roo Code Cloud provider in Settings to get started.",
299+
"goToSettingsButton": "Go to Settings"
300+
},
301+
"socialLinks": "Join us on <xLink>X</xLink>, <discordLink>Discord</discordLink>, or <redditLink>r/RooCode</redditLink> 🚀"
300302
},
301303
"reasoning": {
302304
"thinking": "Thinking",

0 commit comments

Comments
 (0)