Skip to content

Commit a7c8275

Browse files
daniel-lxsclaudecte
authored
fix: forward task configuration through stdin-prompt-stream (#11778)
fix: forward task configuration through stdin-prompt-stream protocol The stdin-prompt-stream `start` command only accepted `prompt` — any `configuration` passed via the cloud worker's StartNewTask was silently dropped. This meant custom modes (e.g. `ask-artifacts`), disabled tools, and other task-level settings never reached the extension when running via the CLI harness. Changes: - Add optional `configuration` field to the `start` stdin command - Parse and forward it in `runStdinStreamMode` - Thread it through `ExtensionHost.runTask` → `newTask` webview message → `ClineProvider.createTask` (which already calls `setValues`) - Add `taskConfiguration` field to `WebviewMessage` type Backward-compatible: older CLIs ignore the extra field; older workers that don't send `configuration` trigger no change in behavior. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: cte <cestreich@gmail.com>
1 parent 81047a6 commit a7c8275

File tree

5 files changed

+30
-8
lines changed

5 files changed

+30
-8
lines changed

apps/cli/src/agent/extension-host.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ interface WebviewViewProvider {
108108
export interface ExtensionHostInterface extends IExtensionHost<ExtensionHostEventMap> {
109109
client: ExtensionClient
110110
activate(): Promise<void>
111-
runTask(prompt: string, taskId?: string): Promise<void>
111+
runTask(prompt: string, taskId?: string, configuration?: RooCodeSettings): Promise<void>
112112
resumeTask(taskId: string): Promise<void>
113113
sendToExtension(message: WebviewMessage): void
114114
dispose(): Promise<void>
@@ -510,8 +510,8 @@ export class ExtensionHost extends EventEmitter implements ExtensionHostInterfac
510510
})
511511
}
512512

513-
public async runTask(prompt: string, taskId?: string): Promise<void> {
514-
this.sendToExtension({ type: "newTask", text: prompt, taskId })
513+
public async runTask(prompt: string, taskId?: string, configuration?: RooCodeSettings): Promise<void> {
514+
this.sendToExtension({ type: "newTask", text: prompt, taskId, taskConfiguration: configuration })
515515
return this.waitForTaskCompletion()
516516
}
517517

apps/cli/src/commands/cli/stdin-stream.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { createInterface } from "readline"
22
import { randomUUID } from "crypto"
33

4+
import type { RooCodeSettings } from "@roo-code/types"
5+
46
import { isRecord } from "@/lib/utils/guards.js"
57

68
import type { ExtensionHost } from "@/agent/index.js"
@@ -13,7 +15,7 @@ import type { JsonEventEmitter } from "@/agent/json-event-emitter.js"
1315
export type StdinStreamCommandName = "start" | "message" | "cancel" | "ping" | "shutdown"
1416

1517
export type StdinStreamCommand =
16-
| { command: "start"; requestId: string; prompt: string }
18+
| { command: "start"; requestId: string; prompt: string; configuration?: RooCodeSettings }
1719
| { command: "message"; requestId: string; prompt: string }
1820
| { command: "cancel"; requestId: string }
1921
| { command: "ping"; requestId: string }
@@ -64,6 +66,10 @@ export function parseStdinStreamCommand(line: string, lineNumber: number): Stdin
6466
throw new Error(`stdin command line ${lineNumber}: "${command}" requires non-empty string "prompt"`)
6567
}
6668

69+
if (command === "start" && isRecord(parsed.configuration)) {
70+
return { command, requestId, prompt: promptRaw, configuration: parsed.configuration as RooCodeSettings }
71+
}
72+
6773
return { command, requestId, prompt: promptRaw }
6874
}
6975

@@ -488,7 +494,7 @@ export async function runStdinStreamMode({ host, jsonEmitter, setStreamRequestId
488494
})
489495

490496
activeTaskPromise = host
491-
.runTask(stdinCommand.prompt, latestTaskId)
497+
.runTask(stdinCommand.prompt, latestTaskId, stdinCommand.configuration)
492498
.catch((error) => {
493499
const message = error instanceof Error ? error.message : String(error)
494500

packages/types/src/vscode-extension-host.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,8 @@ export interface WebviewMessage {
679679
codebaseIndexOpenRouterApiKey?: string
680680
}
681681
updatedSettings?: RooCodeSettings
682+
/** Task configuration applied via `createTask()` when starting a cloud task. */
683+
taskConfiguration?: RooCodeSettings
682684
// Worktree properties
683685
worktreePath?: string
684686
worktreeBranch?: string

src/core/webview/ClineProvider.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,16 @@ export class ClineProvider
29222922
if (configuration.currentApiConfigName) {
29232923
await this.setProviderProfile(configuration.currentApiConfigName)
29242924
}
2925+
2926+
// Register custom modes so the CustomModesManager knows about them.
2927+
// setValues writes to global state, but the manager overwrites that
2928+
// when it merges .roomodes + global settings on refresh. Persisting
2929+
// via updateCustomMode ensures modes survive the merge cycle.
2930+
if (configuration.customModes?.length) {
2931+
for (const mode of configuration.customModes) {
2932+
await this.customModesManager.updateCustomMode(mode.slug, mode)
2933+
}
2934+
}
29252935
}
29262936

29272937
const { apiConfiguration, organizationAllowList, enableCheckpoints, checkpointTimeout, experiments } =

src/core/webview/webviewMessageHandler.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,13 @@ export const webviewMessageHandler = async (
554554
// task. This essentially creates a fresh slate for the new task.
555555
try {
556556
const resolved = await resolveIncomingImages({ text: message.text, images: message.images })
557-
await provider.createTask(resolved.text, resolved.images, undefined, {
558-
taskId: message.taskId,
559-
})
557+
await provider.createTask(
558+
resolved.text,
559+
resolved.images,
560+
undefined,
561+
{ taskId: message.taskId },
562+
message.taskConfiguration,
563+
)
560564
// Task created successfully - notify the UI to reset
561565
await provider.postMessageToWebview({ type: "invoke", invoke: "newChat" })
562566
} catch (error) {

0 commit comments

Comments
 (0)