Skip to content

Commit f842381

Browse files
committed
Merge origin/main and resolve conflicts
Merged supportsImages feature with the new options-based API from main: - Added supportsImages to ReadFileToolOptions interface - Added supportsImages to NativeToolsOptions interface - Updated build-tools.ts to pass supportsImages via options object - Combined test suites for maxConcurrentFileReads and supportsImages
2 parents 3ddefd9 + d23824d commit f842381

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+994
-228
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Roo Code Changelog
22

3+
## [3.38.3] - 2026-01-03
4+
5+
- Feat: Add option in Context settings to recursively load `.roo/rules` and `AGENTS.md` from subdirectories (PR #10446 by @mrubens)
6+
- Fix: Stop frequent Claude Code sign-ins by hardening OAuth refresh token handling (PR #10410 by @hannesrudolph)
7+
- Fix: Add `maxConcurrentFileReads` limit to native `read_file` tool schema (PR #10449 by @app/roomote)
8+
- Fix: Add type check for `lastMessage.text` in TTS useEffect to prevent runtime errors (PR #10431 by @app/roomote)
9+
310
## [3.38.2] - 2025-12-31
411

512
![3.38.2 Release - Skill Alignment](/releases/3.38.2-release.png)

packages/types/npm/package.metadata.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.96.0",
3+
"version": "1.99.0",
44
"description": "TypeScript type definitions for Roo Code.",
55
"publishConfig": {
66
"access": "public",

packages/types/src/global-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export const globalSettingsSchema = z.object({
143143
maxOpenTabsContext: z.number().optional(),
144144
maxWorkspaceFiles: z.number().optional(),
145145
showRooIgnoredFiles: z.boolean().optional(),
146+
enableSubfolderRules: z.boolean().optional(),
146147
maxReadFileLine: z.number().optional(),
147148
maxImageFileSize: z.number().optional(),
148149
maxTotalImageSize: z.number().optional(),

src/core/prompts/sections/__tests__/custom-instructions-global.spec.ts

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
import * as path from "path"
22

33
// Use vi.hoisted to ensure mocks are available during hoisting
4-
const { mockHomedir, mockStat, mockReadFile, mockReaddir, mockGetRooDirectoriesForCwd, mockGetGlobalRooDirectory } =
5-
vi.hoisted(() => ({
6-
mockHomedir: vi.fn(),
7-
mockStat: vi.fn(),
8-
mockReadFile: vi.fn(),
9-
mockReaddir: vi.fn(),
10-
mockGetRooDirectoriesForCwd: vi.fn(),
11-
mockGetGlobalRooDirectory: vi.fn(),
12-
}))
4+
const {
5+
mockHomedir,
6+
mockStat,
7+
mockReadFile,
8+
mockReaddir,
9+
mockLstat,
10+
mockGetRooDirectoriesForCwd,
11+
mockGetAllRooDirectoriesForCwd,
12+
mockGetAgentsDirectoriesForCwd,
13+
mockGetGlobalRooDirectory,
14+
} = vi.hoisted(() => ({
15+
mockHomedir: vi.fn(),
16+
mockStat: vi.fn(),
17+
mockReadFile: vi.fn(),
18+
mockReaddir: vi.fn(),
19+
mockLstat: vi.fn(),
20+
mockGetRooDirectoriesForCwd: vi.fn(),
21+
mockGetAllRooDirectoriesForCwd: vi.fn(),
22+
mockGetAgentsDirectoriesForCwd: vi.fn(),
23+
mockGetGlobalRooDirectory: vi.fn(),
24+
}))
1325

1426
// Mock os module
1527
vi.mock("os", () => ({
@@ -25,12 +37,15 @@ vi.mock("fs/promises", () => ({
2537
stat: mockStat,
2638
readFile: mockReadFile,
2739
readdir: mockReaddir,
40+
lstat: mockLstat,
2841
},
2942
}))
3043

3144
// Mock the roo-config service
3245
vi.mock("../../../../services/roo-config", () => ({
3346
getRooDirectoriesForCwd: mockGetRooDirectoriesForCwd,
47+
getAllRooDirectoriesForCwd: mockGetAllRooDirectoriesForCwd,
48+
getAgentsDirectoriesForCwd: mockGetAgentsDirectoriesForCwd,
3449
getGlobalRooDirectory: mockGetGlobalRooDirectory,
3550
}))
3651

@@ -46,7 +61,13 @@ describe("custom-instructions global .roo support", () => {
4661
vi.clearAllMocks()
4762
mockHomedir.mockReturnValue(mockHomeDir)
4863
mockGetRooDirectoriesForCwd.mockReturnValue([globalRooDir, projectRooDir])
64+
// getAllRooDirectoriesForCwd is now async and returns the same directories by default
65+
mockGetAllRooDirectoriesForCwd.mockResolvedValue([globalRooDir, projectRooDir])
66+
// getAgentsDirectoriesForCwd returns parent directories (without .roo)
67+
mockGetAgentsDirectoriesForCwd.mockResolvedValue([mockCwd])
4968
mockGetGlobalRooDirectory.mockReturnValue(globalRooDir)
69+
// Default lstat to reject (file not found)
70+
mockLstat.mockRejectedValue(new Error("ENOENT"))
5071
})
5172

5273
afterEach(() => {
@@ -65,7 +86,11 @@ describe("custom-instructions global .roo support", () => {
6586

6687
// Mock directory reading for global rules
6788
mockReaddir.mockResolvedValueOnce([
68-
{ name: "rules.md", isFile: () => true, isSymbolicLink: () => false } as any,
89+
{
90+
name: "rules.md",
91+
isFile: () => true,
92+
isSymbolicLink: () => false,
93+
} as any,
6994
])
7095

7196
// Mock file reading for the rules.md file
@@ -87,7 +112,11 @@ describe("custom-instructions global .roo support", () => {
87112

88113
// Mock directory reading for project rules
89114
mockReaddir.mockResolvedValueOnce([
90-
{ name: "rules.md", isFile: () => true, isSymbolicLink: () => false } as any,
115+
{
116+
name: "rules.md",
117+
isFile: () => true,
118+
isSymbolicLink: () => false,
119+
} as any,
91120
])
92121

93122
// Mock file reading
@@ -112,8 +141,20 @@ describe("custom-instructions global .roo support", () => {
112141

113142
// Mock directory reading
114143
mockReaddir
115-
.mockResolvedValueOnce([{ name: "global.md", isFile: () => true, isSymbolicLink: () => false } as any])
116-
.mockResolvedValueOnce([{ name: "project.md", isFile: () => true, isSymbolicLink: () => false } as any])
144+
.mockResolvedValueOnce([
145+
{
146+
name: "global.md",
147+
isFile: () => true,
148+
isSymbolicLink: () => false,
149+
} as any,
150+
])
151+
.mockResolvedValueOnce([
152+
{
153+
name: "project.md",
154+
isFile: () => true,
155+
isSymbolicLink: () => false,
156+
} as any,
157+
])
117158

118159
// Mock file reading
119160
mockReadFile.mockResolvedValueOnce("global rule content").mockResolvedValueOnce("project rule content")
@@ -182,10 +223,18 @@ describe("custom-instructions global .roo support", () => {
182223
// Mock directory reading for mode-specific rules
183224
mockReaddir
184225
.mockResolvedValueOnce([
185-
{ name: "global-mode.md", isFile: () => true, isSymbolicLink: () => false } as any,
226+
{
227+
name: "global-mode.md",
228+
isFile: () => true,
229+
isSymbolicLink: () => false,
230+
} as any,
186231
])
187232
.mockResolvedValueOnce([
188-
{ name: "project-mode.md", isFile: () => true, isSymbolicLink: () => false } as any,
233+
{
234+
name: "project-mode.md",
235+
isFile: () => true,
236+
isSymbolicLink: () => false,
237+
} as any,
189238
])
190239

191240
// Mock file reading for mode-specific rules

0 commit comments

Comments
 (0)