Skip to content

Commit fb30376

Browse files
committed
fix(branding): replace remaining user-facing "Roo" strings with "Zoo"
Replace user-facing product references from "Roo" to "Zoo": - Webview panel and editor tab titles - Integrated terminal names - Diff view labels - VS Code LM authorization justification - LM Studio context-length error messages - Missing-parameter tool error (now i18n-keyed via tools:missingToolParameter[WithPath] across all 16 locales) - Webview-ui localization strings (chat, settings, prompts across all locales) Per review feedback, references to the external Roo provider/router remain untouched: the routerRemoval messages, errors.roo/info.roo i18n keys, Roo credit-balance notices, and other internal identifiers that reference the legacy Roo provider rather than our brand.
1 parent b132a6b commit fb30376

63 files changed

Lines changed: 411 additions & 252 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"zoo-code": patch
3+
---
4+
5+
Replace remaining user-facing "Roo" brand strings with "Zoo" across the extension: webview and editor tab titles, terminal names, diff editor labels, VS Code LM authorization prompts, LM Studio error messages, output channel messages, and the missing-tool-parameter error notice (now localized via `tools:missingToolParameter[WithPath]` keys across all 16 locales). Also update corresponding strings in webview-ui localization files (chat, settings, prompts).
6+
7+
References to the external Roo provider/router remain unchanged: the `roo` provider id, `.roo*` config files, `errors.roo`/`info.roo` i18n keys, router-removal notices, Roo Cloud sign-in/credit-balance messages, i18n key paths, attribution headers, and console logs.

src/activate/__tests__/registerCommands.spec.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Mock } from "vitest"
22
import * as vscode from "vscode"
33
import { ClineProvider } from "../../core/webview/ClineProvider"
44

5-
import { getVisibleProviderOrLog, registerCommands, setPanel } from "../registerCommands"
5+
import { getVisibleProviderOrLog, openClineInNewTab, registerCommands, setPanel } from "../registerCommands"
66

77
vi.mock("execa", () => ({
88
execa: vi.fn(),
@@ -13,8 +13,16 @@ vi.mock("vscode", () => ({
1313
QuickFix: { value: "quickfix" },
1414
RefactorRewrite: { value: "refactor.rewrite" },
1515
},
16+
Uri: {
17+
joinPath: vi.fn((_base: unknown, ..._pathSegments: string[]) => ({ path: _pathSegments.join("/") })),
18+
},
19+
ViewColumn: {
20+
Two: 2,
21+
},
1622
window: {
1723
createTextEditorDecorationType: vi.fn().mockReturnValue({ dispose: vi.fn() }),
24+
createWebviewPanel: vi.fn(),
25+
visibleTextEditors: [],
1826
},
1927
workspace: {
2028
workspaceFolders: [
@@ -349,3 +357,53 @@ describe("registerCommands handlers", () => {
349357
)
350358
})
351359
})
360+
361+
describe("openClineInNewTab", () => {
362+
let mockOutputChannel: vscode.OutputChannel
363+
let mockContext: vscode.ExtensionContext
364+
365+
beforeEach(() => {
366+
vi.clearAllMocks()
367+
368+
mockOutputChannel = {
369+
appendLine: vi.fn(),
370+
append: vi.fn(),
371+
clear: vi.fn(),
372+
hide: vi.fn(),
373+
name: "mock",
374+
replace: vi.fn(),
375+
show: vi.fn(),
376+
dispose: vi.fn(),
377+
}
378+
379+
mockContext = {
380+
subscriptions: [],
381+
extensionUri: { path: "/mock/ext" },
382+
} as unknown as vscode.ExtensionContext
383+
384+
const mockPanel = {
385+
webview: { postMessage: vi.fn() },
386+
onDidChangeViewState: vi.fn(),
387+
onDidDispose: vi.fn(),
388+
}
389+
;(vscode.window.createWebviewPanel as Mock).mockReturnValue(mockPanel)
390+
391+
// Reset module-level panel state.
392+
setPanel(undefined, "sidebar")
393+
setPanel(undefined, "tab")
394+
})
395+
396+
it("creates a webview panel with title 'Zoo Code'", async () => {
397+
await openClineInNewTab({ context: mockContext, outputChannel: mockOutputChannel })
398+
399+
expect(vscode.window.createWebviewPanel).toHaveBeenCalledWith(
400+
"zoo-code.TabPanelProvider",
401+
"Zoo Code",
402+
expect.any(Number),
403+
expect.objectContaining({
404+
enableScripts: true,
405+
retainContextWhenHidden: true,
406+
}),
407+
)
408+
})
409+
})

src/activate/registerCommands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export const openClineInNewTab = async ({ context, outputChannel }: Omit<Registe
251251

252252
const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two
253253

254-
const newPanel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Roo Code", targetCol, {
254+
const newPanel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Zoo Code", targetCol, {
255255
enableScripts: true,
256256
retainContextWhenHidden: true,
257257
localResourceRoots: [context.extensionUri],

src/api/providers/lm-studio.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan
164164
} as const
165165
} catch (error) {
166166
throw new Error(
167-
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Roo Code's prompts.",
167+
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Zoo Code's prompts.",
168168
)
169169
}
170170
}
@@ -211,7 +211,7 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan
211211
return response.choices[0]?.message.content || ""
212212
} catch (error) {
213213
throw new Error(
214-
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Roo Code's prompts.",
214+
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Zoo Code's prompts.",
215215
)
216216
}
217217
}

src/api/providers/vscode-lm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ export class VsCodeLmHandler extends BaseProvider implements SingleCompletionHan
395395
try {
396396
// Create the response stream with required options
397397
const requestOptions: vscode.LanguageModelChatRequestOptions = {
398-
justification: `Roo Code would like to use '${client.name}' from '${client.vendor}', Click 'Allow' to proceed.`,
398+
justification: `Zoo Code would like to use '${client.name}' from '${client.vendor}', Click 'Allow' to proceed.`,
399399
tools: convertToVsCodeLmTools(metadata?.tools ?? []),
400400
}
401401

src/core/task/Task.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,9 +1811,13 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
18111811
async sayAndCreateMissingParamError(toolName: ToolName, paramName: string, relPath?: string) {
18121812
await this.say(
18131813
"error",
1814-
`Roo tried to use ${toolName}${
1815-
relPath ? ` for '${relPath.toPosix()}'` : ""
1816-
} without value for required parameter '${paramName}'. Retrying...`,
1814+
relPath
1815+
? t("tools:missingToolParameterWithPath", {
1816+
toolName,
1817+
relPath: relPath.toPosix(),
1818+
paramName,
1819+
})
1820+
: t("tools:missingToolParameter", { toolName, paramName }),
18171821
)
18181822
return formatResponse.toolError(formatResponse.missingToolParameterError(paramName))
18191823
}

src/core/task/__tests__/Task.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,25 @@ vi.mock("../../environment/getEnvironmentDetails", () => ({
160160

161161
vi.mock("../../ignore/RooIgnoreController")
162162

163+
// i18n is not initialized in this suite, so the real t() returns the raw translation key.
164+
// Interpolate just the missing-parameter keys so tests can assert on the resolved, user-facing
165+
// copy; every other key is delegated to the real t() to keep the rest of the suite unchanged.
166+
vi.mock("../../../i18n", async (importOriginal) => {
167+
const actual = (await importOriginal()) as typeof import("../../../i18n")
168+
return {
169+
...actual,
170+
t: (key: string, args?: Record<string, unknown>) => {
171+
if (key === "tools:missingToolParameterWithPath") {
172+
return `Zoo tried to use ${args?.toolName} for '${args?.relPath}' without value for required parameter '${args?.paramName}'. Retrying...`
173+
}
174+
if (key === "tools:missingToolParameter") {
175+
return `Zoo tried to use ${args?.toolName} without value for required parameter '${args?.paramName}'. Retrying...`
176+
}
177+
return actual.t(key, args)
178+
},
179+
}
180+
})
181+
163182
vi.mock("../../condense", async (importOriginal) => {
164183
const actual = (await importOriginal()) as any
165184
return {
@@ -400,6 +419,41 @@ describe("Cline", () => {
400419
})
401420
})
402421

422+
describe("sayAndCreateMissingParamError", () => {
423+
it("surfaces a localized error notice and returns the missing-parameter tool error for both relPath branches", async () => {
424+
const cline = new Task({
425+
provider: mockProvider,
426+
apiConfiguration: mockApiConfig,
427+
task: "test task",
428+
startTask: false,
429+
})
430+
431+
const saySpy = vi.spyOn(cline, "say").mockResolvedValue(undefined)
432+
433+
// relPath provided -> the "...WithPath" message branch.
434+
const withPath = await cline.sayAndCreateMissingParamError("read_file", "path", "src/foo.ts")
435+
// relPath omitted -> the plain message branch.
436+
const withoutPath = await cline.sayAndCreateMissingParamError("execute_command", "command")
437+
438+
// Both branches emit an "error" say whose resolved text names the tool and the
439+
// missing parameter (guards against a silent i18n regression where t() would
440+
// otherwise return the raw key or an empty string and still type-check as a String).
441+
expect(saySpy).toHaveBeenCalledTimes(2)
442+
const [withPathChannel, withPathNotice] = saySpy.mock.calls[0]
443+
const [withoutPathChannel, withoutPathNotice] = saySpy.mock.calls[1]
444+
expect(withPathChannel).toBe("error")
445+
expect(withoutPathChannel).toBe("error")
446+
expect(withPathNotice).toEqual(expect.stringContaining("read_file"))
447+
expect(withPathNotice).toEqual(expect.stringContaining("path"))
448+
expect(withoutPathNotice).toEqual(expect.stringContaining("execute_command"))
449+
expect(withoutPathNotice).toEqual(expect.stringContaining("command"))
450+
451+
// The returned tool error names the missing parameter.
452+
expect(withPath).toContain("path")
453+
expect(withoutPath).toContain("command")
454+
})
455+
})
456+
403457
describe("getEnvironmentDetails", () => {
404458
describe("API conversation handling", () => {
405459
it("should strip non-protocol fields from API conversation history before sending to the API", async () => {

src/core/webview/ClineProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ export class ClineProvider
13411341
window.AUDIO_BASE_URI = "${audioUri}"
13421342
window.MATERIAL_ICONS_BASE_URI = "${materialIconsUri}"
13431343
</script>
1344-
<title>Roo Code</title>
1344+
<title>Zoo Code</title>
13451345
</head>
13461346
<body>
13471347
<div id="root"></div>
@@ -1420,7 +1420,7 @@ export class ClineProvider
14201420
window.AUDIO_BASE_URI = "${audioUri}"
14211421
window.MATERIAL_ICONS_BASE_URI = "${materialIconsUri}"
14221422
</script>
1423-
<title>Roo Code</title>
1423+
<title>Zoo Code</title>
14241424
</head>
14251425
<body>
14261426
<noscript>You need to enable JavaScript to run this app.</noscript>

src/i18n/locales/ca/tools.json

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

src/i18n/locales/de/tools.json

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

0 commit comments

Comments
 (0)