Skip to content

Commit d61cb16

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/issue-4258-latex-rendering
2 parents 4bad1fa + 3e2aec2 commit d61cb16

File tree

7 files changed

+90
-13
lines changed

7 files changed

+90
-13
lines changed

.roomodes

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ customModes:
2828
- slug: test
2929
name: 🧪 Test
3030
roleDefinition: >-
31-
You are Roo, a Jest testing specialist with deep expertise in:
32-
- Writing and maintaining Jest test suites
31+
You are Roo, a Vitest testing specialist with deep expertise in:
32+
- Writing and maintaining Vitest test suites
3333
- Test-driven development (TDD) practices
34-
- Mocking and stubbing with Jest
34+
- Mocking and stubbing with Vitest
3535
- Integration testing strategies
3636
- TypeScript testing patterns
3737
- Code coverage analysis
@@ -41,21 +41,23 @@ customModes:
4141
- Test files in __tests__ directories
4242
- Mock implementations in __mocks__
4343
- Test utilities and helpers
44-
- Jest configuration and setup
44+
- Vitest configuration and setup
4545

4646
You ensure tests are:
4747
- Well-structured and maintainable
48-
- Following Jest best practices
48+
- Following Vitest best practices
4949
- Properly typed with TypeScript
5050
- Providing meaningful coverage
5151
- Using appropriate mocking strategies
52+
whenToUse: >-
53+
Use this mode when you need to write, modify, or maintain tests for the codebase.
5254
groups:
5355
- read
5456
- browser
5557
- command
5658
- - edit
57-
- fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|/test/.*|jest\.config\.(js|ts)$)
58-
description: Test files, mocks, and Jest configuration
59+
- fileRegex: (__tests__/.*|__mocks__/.*|\.test\.(ts|tsx|js|jsx)$|\.spec\.(ts|tsx|js|jsx)$|/test/.*|vitest\.config\.(js|ts)$|vitest\.setup\.(js|ts)$)
60+
description: Test files, mocks, and Vitest configuration
5961
customInstructions: |-
6062
When writing tests:
6163
- Always use describe/it blocks for clear test organization
@@ -66,6 +68,8 @@ customModes:
6668
- Ensure mocks are properly typed
6769
- Verify both positive and negative test cases
6870
- Always use data-testid attributes when testing webview-ui
71+
- The vitest framework is used for testing; the `describe`, `test`, `it`, etc functions are defined by default in `tsconfig.json` and therefore don't need to be imported
72+
- Tests must be run from the same directory as the `package.json` file that specifies `vitest` in `devDependencies`
6973
- slug: design-engineer
7074
name: 🎨 Design Engineer
7175
roleDefinition: >-

packages/types/npm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@roo-code/types",
3-
"version": "1.26.0",
3+
"version": "1.27.0",
44
"description": "TypeScript type definitions for Roo Code.",
55
"publishConfig": {
66
"access": "public",

packages/types/src/telemetry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export enum TelemetryEventName {
4343

4444
MARKETPLACE_ITEM_INSTALLED = "Marketplace Item Installed",
4545
MARKETPLACE_ITEM_REMOVED = "Marketplace Item Removed",
46+
MARKETPLACE_TAB_VIEWED = "Marketplace Tab Viewed",
47+
MARKETPLACE_INSTALL_BUTTON_CLICKED = "Marketplace Install Button Clicked",
4648

4749
SCHEMA_VALIDATION_ERROR = "Schema Validation Error",
4850
DIFF_APPLICATION_ERROR = "Diff Application Error",

src/core/environment/__tests__/getEnvironmentDetails.spec.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ describe("getEnvironmentDetails", () => {
5959
getLastCommand: Mock
6060
getProcessesWithOutput: Mock
6161
cleanCompletedProcessQueue?: Mock
62+
getCurrentWorkingDirectory: Mock
6263
}
6364

6465
let mockCline: Partial<Task>
@@ -208,6 +209,7 @@ describe("getEnvironmentDetails", () => {
208209
id: "terminal-1",
209210
getLastCommand: vi.fn().mockReturnValue("npm test"),
210211
getProcessesWithOutput: vi.fn().mockReturnValue([]),
212+
getCurrentWorkingDirectory: vi.fn().mockReturnValue("/test/path/src"),
211213
} as MockTerminal
212214

213215
;(TerminalRegistry.getTerminals as Mock).mockReturnValue([mockActiveTerminal])
@@ -216,7 +218,9 @@ describe("getEnvironmentDetails", () => {
216218
const result = await getEnvironmentDetails(mockCline as Task)
217219

218220
expect(result).toContain("# Actively Running Terminals")
219-
expect(result).toContain("Original command: `npm test`")
221+
expect(result).toContain("## Terminal terminal-1 (Active)")
222+
expect(result).toContain("### Working Directory: `/test/path/src`")
223+
expect(result).toContain("### Original command: `npm test`")
220224
expect(result).toContain("Test output")
221225

222226
mockCline.didEditFile = true
@@ -234,8 +238,10 @@ describe("getEnvironmentDetails", () => {
234238

235239
const mockInactiveTerminal = {
236240
id: "terminal-2",
241+
getLastCommand: vi.fn().mockReturnValue("npm build"),
237242
getProcessesWithOutput: vi.fn().mockReturnValue([mockProcess]),
238243
cleanCompletedProcessQueue: vi.fn(),
244+
getCurrentWorkingDirectory: vi.fn().mockReturnValue("/test/path/build"),
239245
} as MockTerminal
240246

241247
;(TerminalRegistry.getTerminals as Mock).mockImplementation((active: boolean) =>
@@ -245,13 +251,56 @@ describe("getEnvironmentDetails", () => {
245251
const result = await getEnvironmentDetails(mockCline as Task)
246252

247253
expect(result).toContain("# Inactive Terminals with Completed Process Output")
248-
expect(result).toContain("Terminal terminal-2")
254+
expect(result).toContain("## Terminal terminal-2 (Inactive)")
255+
expect(result).toContain("### Working Directory: `/test/path/build`")
249256
expect(result).toContain("Command: `npm build`")
250257
expect(result).toContain("Build output")
251258

252259
expect(mockInactiveTerminal.cleanCompletedProcessQueue).toHaveBeenCalled()
253260
})
254261

262+
it("should include working directory for terminals", async () => {
263+
const mockActiveTerminal = {
264+
id: "terminal-1",
265+
getLastCommand: vi.fn().mockReturnValue("cd /some/path && npm start"),
266+
getProcessesWithOutput: vi.fn().mockReturnValue([]),
267+
getCurrentWorkingDirectory: vi.fn().mockReturnValue("/some/path"),
268+
} as MockTerminal
269+
270+
const mockProcess = {
271+
command: "npm test",
272+
getUnretrievedOutput: vi.fn().mockReturnValue("Test completed"),
273+
}
274+
275+
const mockInactiveTerminal = {
276+
id: "terminal-2",
277+
getLastCommand: vi.fn().mockReturnValue("npm test"),
278+
getProcessesWithOutput: vi.fn().mockReturnValue([mockProcess]),
279+
cleanCompletedProcessQueue: vi.fn(),
280+
getCurrentWorkingDirectory: vi.fn().mockReturnValue("/another/path"),
281+
} as MockTerminal
282+
283+
;(TerminalRegistry.getTerminals as Mock).mockImplementation((active: boolean) =>
284+
active ? [mockActiveTerminal] : [mockInactiveTerminal],
285+
)
286+
;(TerminalRegistry.getUnretrievedOutput as Mock).mockReturnValue("Server started")
287+
288+
const result = await getEnvironmentDetails(mockCline as Task)
289+
290+
// Check active terminal working directory
291+
expect(result).toContain("## Terminal terminal-1 (Active)")
292+
expect(result).toContain("### Working Directory: `/some/path`")
293+
expect(result).toContain("### Original command: `cd /some/path && npm start`")
294+
295+
// Check inactive terminal working directory
296+
expect(result).toContain("## Terminal terminal-2 (Inactive)")
297+
expect(result).toContain("### Working Directory: `/another/path`")
298+
299+
// Verify the methods were called
300+
expect(mockActiveTerminal.getCurrentWorkingDirectory).toHaveBeenCalled()
301+
expect(mockInactiveTerminal.getCurrentWorkingDirectory).toHaveBeenCalled()
302+
})
303+
255304
it("should include warning when file writing is not allowed", async () => {
256305
;(isToolAllowedForMode as Mock).mockReturnValue(false)
257306
;(getModeBySlug as Mock).mockImplementation((slug: string) => {
@@ -310,6 +359,7 @@ describe("getEnvironmentDetails", () => {
310359
id: "terminal-1",
311360
getLastCommand: vi.fn().mockReturnValue("npm test"),
312361
getProcessesWithOutput: vi.fn().mockReturnValue([]),
362+
getCurrentWorkingDirectory: vi.fn().mockReturnValue("/test/path"),
313363
} as MockTerminal
314364

315365
;(TerminalRegistry.getTerminals as Mock).mockReturnValue([mockErrorTerminal])

src/core/environment/getEnvironmentDetails.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
103103
terminalDetails += "\n\n# Actively Running Terminals"
104104

105105
for (const busyTerminal of busyTerminals) {
106-
terminalDetails += `\n## Original command: \`${busyTerminal.getLastCommand()}\``
106+
const cwd = busyTerminal.getCurrentWorkingDirectory()
107+
terminalDetails += `\n## Terminal ${busyTerminal.id} (Active)`
108+
terminalDetails += `\n### Working Directory: \`${cwd}\``
109+
terminalDetails += `\n### Original command: \`${busyTerminal.getLastCommand()}\``
107110
let newOutput = TerminalRegistry.getUnretrievedOutput(busyTerminal.id)
108111

109112
if (newOutput) {
@@ -145,7 +148,9 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
145148

146149
// Add this terminal's outputs to the details.
147150
if (terminalOutputs.length > 0) {
148-
terminalDetails += `\n## Terminal ${inactiveTerminal.id}`
151+
const cwd = inactiveTerminal.getCurrentWorkingDirectory()
152+
terminalDetails += `\n## Terminal ${inactiveTerminal.id} (Inactive)`
153+
terminalDetails += `\n### Working Directory: \`${cwd}\``
149154
terminalOutputs.forEach((output) => {
150155
terminalDetails += `\n### New Output\n${output}`
151156
})

webview-ui/src/App.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { MarketplaceViewStateManager } from "./components/marketplace/Marketplac
88

99
import { vscode } from "./utils/vscode"
1010
import { telemetryClient } from "./utils/TelemetryClient"
11+
import { TelemetryEventName } from "@roo-code/types"
1112
import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
1213
import ChatView, { ChatViewRef } from "./components/chat/ChatView"
1314
import HistoryView from "./components/history/HistoryView"
@@ -144,6 +145,13 @@ const App = () => {
144145
// Tell the extension that we are ready to receive messages.
145146
useEffect(() => vscode.postMessage({ type: "webviewDidLaunch" }), [])
146147

148+
// Track marketplace tab views
149+
useEffect(() => {
150+
if (tab === "marketplace" && experiments.marketplace) {
151+
telemetryClient.capture(TelemetryEventName.MARKETPLACE_TAB_VIEWED)
152+
}
153+
}, [tab, experiments.marketplace])
154+
147155
if (!didHydrateState) {
148156
return null
149157
}

webview-ui/src/components/marketplace/components/MarketplaceItemCard.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useMemo, useState } from "react"
2-
import { MarketplaceItem } from "@roo-code/types"
2+
import { MarketplaceItem, TelemetryEventName } from "@roo-code/types"
33
import { vscode } from "@/utils/vscode"
4+
import { telemetryClient } from "@/utils/TelemetryClient"
45
import { ViewState } from "../MarketplaceViewStateManager"
56
import { useAppTranslation } from "@/i18n/TranslationContext"
67
import { isValidUrl } from "../../../utils/url"
@@ -43,6 +44,13 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({ item,
4344
const isInstalled = isInstalledGlobally || isInstalledInProject
4445

4546
const handleInstallClick = () => {
47+
// Send telemetry for install button click
48+
telemetryClient.capture(TelemetryEventName.MARKETPLACE_INSTALL_BUTTON_CLICKED, {
49+
itemId: item.id,
50+
itemType: item.type,
51+
itemName: item.name,
52+
})
53+
4654
// Show modal for all item types (MCP and modes)
4755
setShowInstallModal(true)
4856
}

0 commit comments

Comments
 (0)