Skip to content

Commit 119b8b5

Browse files
committed
fix(task): pass null targetTask to handleModeSwitch for slash commands
1 parent c8c3926 commit 119b8b5

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

‎src/core/task/Task.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3091,7 +3091,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
30913091
const state = await provider.getState()
30923092
const targetMode = getModeBySlug(slashCommandMode, state?.customModes)
30933093
if (targetMode) {
3094-
await provider.handleModeSwitch(slashCommandMode)
3094+
await provider.handleModeSwitch(slashCommandMode, null)
30953095
}
30963096
}
30973097
}

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,52 @@ describe("Cline", () => {
19091909
})
19101910
})
19111911

1912+
describe("slash command mode switch", () => {
1913+
it("passes null as targetTask so handleModeSwitch does not overwrite the orchestrator task", async () => {
1914+
const task = new Task({
1915+
provider: mockProvider,
1916+
apiConfiguration: mockApiConfig,
1917+
task: "test task",
1918+
startTask: false,
1919+
})
1920+
1921+
const ensureModelFetched = vi.fn().mockResolvedValue(undefined)
1922+
Object.assign(task.api, { ensureModelFetched })
1923+
vi.spyOn(task.api, "getModel").mockReturnValue({
1924+
id: mockApiConfig.apiModelId!,
1925+
info: {
1926+
supportsImages: false,
1927+
supportsPromptCache: true,
1928+
contextWindow: 200_000,
1929+
maxTokens: 4096,
1930+
} as ModelInfo,
1931+
})
1932+
vi.mocked(processUserContentMentions).mockResolvedValueOnce({
1933+
content: [{ type: "text", text: "run /commit" }],
1934+
mode: "code",
1935+
})
1936+
vi.spyOn(getTaskTestAccess(task), "saveClineMessages").mockResolvedValue(true)
1937+
vi.spyOn(task.diffViewProvider, "reset").mockResolvedValue(undefined as never)
1938+
vi.spyOn(getTaskTestAccess(task), "addToApiConversationHistory").mockResolvedValue(undefined)
1939+
task.clineMessages = [{ ts: Date.now(), type: "say", say: "api_req_started", text: "{}" }]
1940+
vi.spyOn(task, "say").mockImplementation(async (type) => {
1941+
if (type === "api_req_started") {
1942+
task.clineMessages.push({ ts: Date.now(), type: "say", say: "api_req_started", text: "{}" })
1943+
}
1944+
return undefined as never
1945+
})
1946+
vi.spyOn(task, "attemptApiRequest").mockImplementation(() => {
1947+
throw new Error("stop after mode switch")
1948+
})
1949+
1950+
const handleModeSwitchSpy = vi.spyOn(mockProvider, "handleModeSwitch").mockResolvedValue(undefined)
1951+
1952+
await task.recursivelyMakeClineRequests([{ type: "text", text: "run /commit" }]).catch(() => {})
1953+
1954+
expect(handleModeSwitchSpy).toHaveBeenCalledWith("code", null)
1955+
})
1956+
})
1957+
19121958
describe("Subtask Rate Limiting", () => {
19131959
let mockProvider: MockedClineProvider
19141960
let mockApiConfig: RateLimitedProviderSettings

0 commit comments

Comments
 (0)