diff --git a/packages/core/src/cross-spawn-spawner.ts b/packages/core/src/cross-spawn-spawner.ts index ad8d4126d454..3bfc4664a4e5 100644 --- a/packages/core/src/cross-spawn-spawner.ts +++ b/packages/core/src/cross-spawn-spawner.ts @@ -393,7 +393,11 @@ export const make = Effect.gen(function* () { const escalated = command.options.forceKillAfter ? Effect.timeoutOrElse(attempt, { duration: command.options.forceKillAfter, - orElse: () => send("SIGKILL").pipe(Effect.andThen(Deferred.await(signal)), Effect.asVoid), + orElse: () => + send("SIGKILL").pipe( + Effect.andThen(Deferred.await(signal).pipe(Effect.timeout("5 seconds"), Effect.ignore)), + Effect.asVoid, + ), }) : attempt return yield* Effect.ignore(escalated) @@ -430,7 +434,11 @@ export const make = Effect.gen(function* () { if (!opts?.forceKillAfter) return attempt return Effect.timeoutOrElse(attempt, { duration: opts.forceKillAfter, - orElse: () => send("SIGKILL").pipe(Effect.andThen(Deferred.await(signal)), Effect.asVoid), + orElse: () => + send("SIGKILL").pipe( + Effect.andThen(Deferred.await(signal).pipe(Effect.timeout("5 seconds"), Effect.ignore)), + Effect.asVoid, + ), }) }, unref: Effect.sync(() => { diff --git a/packages/opencode/src/tool/shell.ts b/packages/opencode/src/tool/shell.ts index 506d98466e76..4eadba2ebcde 100644 --- a/packages/opencode/src/tool/shell.ts +++ b/packages/opencode/src/tool/shell.ts @@ -627,6 +627,16 @@ export const ShellTool = Tool.define( if (!containsPath(cwd, instanceCtx)) scan.dirs.add(cwd) yield* ask(ctx, scan) }), + ).pipe( + Effect.timeoutOrElse({ + duration: "10 seconds", + orElse: () => + Effect.gen(function* () { + yield* Effect.logWarning( + "Shell command scan/ask phase timed out after 10 seconds; continuing execution without completing that work, so results may be incomplete.", + ) + }), + }), ) return yield* run(