mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-14 23:21:19 +00:00
feat(cli): include exitCode in command tool_result events (#11820)
Propagate the command exit code through the JSON event emitter so CLI consumers can distinguish between successful and failed command executions without parsing output text. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7118a14188
commit
eb2147148e
4 changed files with 28 additions and 7 deletions
|
|
@ -302,7 +302,7 @@ describe("JsonEventEmitter streaming deltas", () => {
|
|||
|
||||
emitter.emitCommandOutputChunk("line1\n")
|
||||
emitter.emitCommandOutputChunk("line1\nline2\n")
|
||||
emitter.emitCommandOutputDone()
|
||||
emitter.emitCommandOutputDone(17)
|
||||
|
||||
// This completion say is expected from the extension, but should be suppressed
|
||||
// because we already streamed and completed via commandExecutionStatus.
|
||||
|
|
@ -339,7 +339,7 @@ describe("JsonEventEmitter streaming deltas", () => {
|
|||
type: "tool_result",
|
||||
id: commandId,
|
||||
subtype: "command",
|
||||
tool_result: { name: "execute_command" },
|
||||
tool_result: { name: "execute_command", exitCode: 17 },
|
||||
done: true,
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -310,7 +310,12 @@ export class JsonEventEmitter {
|
|||
return normalized.startsWith(previous) ? normalized.slice(previous.length) : normalized
|
||||
}
|
||||
|
||||
private emitCommandOutputEvent(commandId: number, fullOutput: string | undefined, isDone: boolean): void {
|
||||
private emitCommandOutputEvent(
|
||||
commandId: number,
|
||||
fullOutput: string | undefined,
|
||||
isDone: boolean,
|
||||
exitCode?: number,
|
||||
): void {
|
||||
if (this.mode === "stream-json") {
|
||||
const outputDelta = this.computeCommandOutputDelta(commandId, fullOutput)
|
||||
const event: JsonEvent = {
|
||||
|
|
@ -324,6 +329,13 @@ export class JsonEventEmitter {
|
|||
event.tool_result = { name: "execute_command", output: outputDelta }
|
||||
}
|
||||
|
||||
if (isDone && exitCode !== undefined) {
|
||||
event.tool_result = {
|
||||
...(event.tool_result ?? { name: "execute_command" }),
|
||||
exitCode,
|
||||
}
|
||||
}
|
||||
|
||||
if (isDone) {
|
||||
event.done = true
|
||||
this.previousCommandOutputByToolUseId.delete(commandId)
|
||||
|
|
@ -347,7 +359,11 @@ export class JsonEventEmitter {
|
|||
type: "tool_result",
|
||||
id: commandId,
|
||||
subtype: "command",
|
||||
tool_result: { name: "execute_command", output: fullOutput },
|
||||
tool_result: {
|
||||
name: "execute_command",
|
||||
output: fullOutput,
|
||||
...(isDone && exitCode !== undefined ? { exitCode } : {}),
|
||||
},
|
||||
...(isDone ? { done: true } : {}),
|
||||
})
|
||||
|
||||
|
|
@ -371,7 +387,7 @@ export class JsonEventEmitter {
|
|||
this.emitCommandOutputEvent(commandId, outputSnapshot, false)
|
||||
}
|
||||
|
||||
public emitCommandOutputDone(): void {
|
||||
public emitCommandOutputDone(exitCode?: number): void {
|
||||
const commandId = this.activeCommandToolUseId
|
||||
if (commandId === undefined) {
|
||||
return
|
||||
|
|
@ -379,7 +395,7 @@ export class JsonEventEmitter {
|
|||
|
||||
this.statusDrivenCommandOutputIds.add(commandId)
|
||||
this.suppressNextCommandOutputSay = true
|
||||
this.emitCommandOutputEvent(commandId, undefined, true)
|
||||
this.emitCommandOutputEvent(commandId, undefined, true, exitCode)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -419,7 +419,11 @@ export async function runStdinStreamMode({ host, jsonEmitter, setStreamRequestId
|
|||
parsedStatus.status === "timeout" ||
|
||||
parsedStatus.status === "fallback"
|
||||
) {
|
||||
jsonEmitter.emitCommandOutputDone()
|
||||
const exitCode =
|
||||
parsedStatus.status === "exited" && typeof parsedStatus.exitCode === "number"
|
||||
? parsedStatus.exitCode
|
||||
: undefined
|
||||
jsonEmitter.emitCommandOutputDone(exitCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ export const rooCliToolResultSchema = z.object({
|
|||
name: z.string(),
|
||||
output: z.string().optional(),
|
||||
error: z.string().optional(),
|
||||
exitCode: z.number().optional(),
|
||||
})
|
||||
|
||||
export type RooCliToolResult = z.infer<typeof rooCliToolResultSchema>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue