Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions packages/opencode/src/cli/cmd/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,13 @@ export const RunCommand = effectCmd({
async function loop(client: OpencodeClient, events: Awaited<ReturnType<typeof sdk.event.subscribe>>) {
const toggles = new Map<string, boolean>()
let error: string | undefined
let activeSteps = 0
let pendingIdle = false
let idleTimeoutHandle: ReturnType<typeof setTimeout> | undefined
let idleTimedOut = false

for await (const event of events.stream) {
if (idleTimedOut) break
if (
event.type === "message.updated" &&
event.properties.sessionID === sessionID &&
Expand Down Expand Up @@ -673,11 +678,17 @@ export const RunCommand = effectCmd({
}

if (part.type === "step-start") {
activeSteps++
if (emit("step_start", { part })) continue
}

if (part.type === "step-finish") {
if (emit("step_finish", { part })) continue
activeSteps = Math.max(0, activeSteps - 1)
if (emit("step_finish", { part })) {
if (pendingIdle && activeSteps <= 0) { clearTimeout(idleTimeoutHandle); break }
continue
}
if (pendingIdle && activeSteps <= 0) { clearTimeout(idleTimeoutHandle); break }
}

if (part.type === "text" && part.time?.end) {
Expand Down Expand Up @@ -716,15 +727,24 @@ export const RunCommand = effectCmd({
err = String(props.error.data.message)
}
error = error ? error + EOL + err : err
if (emit("error", { error: props.error })) continue
if (emit("error", { error: props.error })) {
if (pendingIdle) { clearTimeout(idleTimeoutHandle); break }
continue
}
UI.error(err)
if (pendingIdle) { clearTimeout(idleTimeoutHandle); break }
}

if (
event.type === "session.status" &&
event.properties.sessionID === sessionID &&
event.properties.status.type === "idle"
) {
if (activeSteps > 0) {
pendingIdle = true
idleTimeoutHandle = setTimeout(() => { idleTimedOut = true }, 3_000)
continue
}
break
}

Expand All @@ -750,6 +770,7 @@ export const RunCommand = effectCmd({
}
}
}
clearTimeout(idleTimeoutHandle)
return error
}
const cwd = args.attach ? (directory ?? sess.directory ?? (await current(sdk))) : (directory ?? root)
Expand Down
Loading