Skip to content

Commit 97e969a

Browse files
committed
fix: update remaining files to use vscode-aware wrapper functions
- Update custom-system-prompt.ts to use async getSystemPromptFilePath - Update ClineProvider.ts to handle async change - Update MarketplaceManager.ts to use getProjectRooDirectoryForCwd wrapper - Update webviewMessageHandler.ts to use wrapper (already done) This ensures all .roo path constructions properly check for workspace folders
1 parent 86c6af1 commit 97e969a

File tree

5 files changed

+86
-16
lines changed

5 files changed

+86
-16
lines changed

src/core/prompts/sections/custom-system-prompt.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from "fs/promises"
22
import path from "path"
33
import { Mode } from "../../../shared/modes"
44
import { fileExistsAtPath } from "../../../utils/fs"
5+
import { getProjectRooDirectoryForCwd } from "../../../services/roo-config/wrapper"
56

67
export type PromptVariables = {
78
workspace?: string
@@ -45,16 +46,17 @@ async function safeReadFile(filePath: string): Promise<string> {
4546
/**
4647
* Get the path to a system prompt file for a specific mode
4748
*/
48-
export function getSystemPromptFilePath(cwd: string, mode: Mode): string {
49-
return path.join(cwd, ".roo", `system-prompt-${mode}`)
49+
export async function getSystemPromptFilePath(cwd: string, mode: Mode): Promise<string> {
50+
const rooDir = await getProjectRooDirectoryForCwd(cwd)
51+
return path.join(rooDir, `system-prompt-${mode}`)
5052
}
5153

5254
/**
5355
* Loads custom system prompt from a file at .roo/system-prompt-[mode slug]
5456
* If the file doesn't exist, returns an empty string
5557
*/
5658
export async function loadSystemPromptFile(cwd: string, mode: Mode, variables: PromptVariables): Promise<string> {
57-
const filePath = getSystemPromptFilePath(cwd, mode)
59+
const filePath = await getSystemPromptFilePath(cwd, mode)
5860
const rawContent = await safeReadFile(filePath)
5961
if (!rawContent) {
6062
return ""
@@ -67,7 +69,7 @@ export async function loadSystemPromptFile(cwd: string, mode: Mode, variables: P
6769
* Ensures the .roo directory exists, creating it if necessary
6870
*/
6971
export async function ensureRooDirectory(cwd: string): Promise<void> {
70-
const rooDir = path.join(cwd, ".roo")
72+
const rooDir = await getProjectRooDirectoryForCwd(cwd)
7173

7274
// Check if directory already exists
7375
if (await fileExistsAtPath(rooDir)) {

src/core/webview/ClineProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ export class ClineProvider
15381538
* Checks if there is a file-based system prompt override for the given mode
15391539
*/
15401540
async hasFileBasedSystemPromptOverride(mode: Mode): Promise<boolean> {
1541-
const promptFilePath = getSystemPromptFilePath(this.cwd, mode)
1541+
const promptFilePath = await getSystemPromptFilePath(this.cwd, mode)
15421542
return await fileExistsAtPath(promptFilePath)
15431543
}
15441544

src/services/marketplace/MarketplaceManager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { GlobalFileNames } from "../../shared/globalFileNames"
1212
import { ensureSettingsDirectoryExists } from "../../utils/globalContext"
1313
import { t } from "../../i18n"
1414
import type { CustomModesManager } from "../../core/config/CustomModesManager"
15+
import { getProjectRooDirectoryForCwd } from "../../services/roo-config/wrapper"
1516

1617
import { RemoteConfigLoader } from "./RemoteConfigLoader"
1718
import { SimpleInstaller } from "./SimpleInstaller"
@@ -270,7 +271,8 @@ export class MarketplaceManager {
270271
}
271272

272273
// Check MCPs in .roo/mcp.json
273-
const projectMcpPath = path.join(workspaceFolder.uri.fsPath, ".roo", "mcp.json")
274+
const rooDir = await getProjectRooDirectoryForCwd(workspaceFolder.uri.fsPath)
275+
const projectMcpPath = path.join(rooDir, "mcp.json")
274276
try {
275277
const content = await fs.readFile(projectMcpPath, "utf-8")
276278
const data = JSON.parse(content)

src/services/roo-config/__tests__/index.spec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,12 @@ vi.mock("vscode", () => ({
3535
},
3636
}))
3737

38-
import {
39-
getGlobalRooDirectory,
40-
getProjectRooDirectoryForCwd,
41-
directoryExists,
42-
fileExists,
43-
readFileIfExists,
44-
getRooDirectoriesForCwd,
45-
loadConfiguration,
46-
} from "../index"
38+
import { getGlobalRooDirectory, directoryExists, fileExists, readFileIfExists, loadConfiguration } from "../index"
4739
import { findWorkspaceWithRoo } from "../vscode-utils"
40+
import { getProjectRooDirectoryForCwd, getRooDirectoriesForCwd, setVscodeUtils } from "../wrapper"
41+
42+
// Initialize the wrapper with vscode utilities for testing
43+
setVscodeUtils({ findWorkspaceWithRoo })
4844

4945
describe("RooConfigService", () => {
5046
beforeEach(() => {

src/services/roo-config/wrapper.ts

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import * as path from "path"
2-
import { getProjectRooDirectoryForCwd as getProjectRooDirectoryBase } from "./index"
2+
import {
3+
getProjectRooDirectoryForCwd as getProjectRooDirectoryBase,
4+
getGlobalRooDirectory,
5+
getRooDirectoriesForCwd as getRooDirectoriesBase,
6+
loadConfiguration as loadConfigurationBase,
7+
} from "./index"
38

49
// This will be set by the extension during activation
510
let vscodeUtils: { findWorkspaceWithRoo: () => any } | undefined
@@ -28,3 +33,68 @@ export function getProjectRooDirectoryForCwd(cwd: string): string {
2833
// Fall back to base implementation
2934
return getProjectRooDirectoryBase(cwd)
3035
}
36+
37+
/**
38+
* Gets the ordered list of .roo directories to check (global first, then project-local)
39+
* This wrapper uses the vscode-aware getProjectRooDirectoryForCwd
40+
*/
41+
export function getRooDirectoriesForCwd(cwd: string): string[] {
42+
const directories: string[] = []
43+
44+
// Add global directory first
45+
directories.push(getGlobalRooDirectory())
46+
47+
// Add project-local directory second (using wrapper version)
48+
directories.push(getProjectRooDirectoryForCwd(cwd))
49+
50+
return directories
51+
}
52+
53+
/**
54+
* Loads configuration from multiple .roo directories with project overriding global
55+
* This wrapper uses the vscode-aware getProjectRooDirectoryForCwd
56+
*/
57+
export async function loadConfiguration(
58+
relativePath: string,
59+
cwd: string,
60+
): Promise<{
61+
global: string | null
62+
project: string | null
63+
merged: string
64+
}> {
65+
// Use the wrapper version of getProjectRooDirectoryForCwd
66+
const globalDir = getGlobalRooDirectory()
67+
const projectDir = getProjectRooDirectoryForCwd(cwd)
68+
69+
const globalFilePath = path.join(globalDir, relativePath)
70+
const projectFilePath = path.join(projectDir, relativePath)
71+
72+
// Import readFileIfExists from index
73+
const { readFileIfExists } = await import("./index")
74+
75+
// Read global configuration
76+
const globalContent = await readFileIfExists(globalFilePath)
77+
78+
// Read project-local configuration
79+
const projectContent = await readFileIfExists(projectFilePath)
80+
81+
// Merge configurations - project overrides global
82+
let merged = ""
83+
84+
if (globalContent) {
85+
merged += globalContent
86+
}
87+
88+
if (projectContent) {
89+
if (merged) {
90+
merged += "\n\n# Project-specific rules (override global):\n\n"
91+
}
92+
merged += projectContent
93+
}
94+
95+
return {
96+
global: globalContent,
97+
project: projectContent,
98+
merged: merged || "",
99+
}
100+
}

0 commit comments

Comments
 (0)