Skip to content
Closed
Show file tree
Hide file tree
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
34 changes: 33 additions & 1 deletion packages/desktop-electron/scripts/report-problem-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,38 @@ function latestMarkdownReport(reportRoot) {
}
}

function childIsRunning(child) {
return child.exitCode === null && child.signalCode === null
}
Comment on lines +58 to +60

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add a defensive check to ensure child is defined before accessing its properties. If app.process() returns undefined or null (e.g., if the application failed to launch or has already been completely disposed), this function will throw a TypeError.

function childIsRunning(child) {
  return child && child.exitCode === null && child.signalCode === null
}


async function withTimeout(promise, ms, timeoutValue) {
let timeout
try {
return await Promise.race([
promise,
new Promise((resolve) => {
timeout = setTimeout(() => resolve(timeoutValue), ms)
}),
])
} finally {
clearTimeout(timeout)
}
}

async function waitForExit(child, ms) {
if (!childIsRunning(child)) return
await withTimeout(new Promise((resolve) => child.once("exit", resolve)), ms, undefined)
}

async function closeApp(app) {
const child = app.process()
const closed = await withTimeout(app.close().then(() => true).catch(() => false), 5_000, false)
if (closed || !childIsRunning(child)) return

child.kill("SIGKILL")
await waitForExit(child, 5_000)
}

const homeDir = mkdtempSync(join(tmpdir(), "pawwork-report-smoke-"))
const app = await electron.launch({
executablePath: require("electron/index.js"),
Expand Down Expand Up @@ -101,6 +133,6 @@ try {
assert(summary.markdownHasRendererError, "expected full report to include renderer error details")
assert(summary.markdownHasReportPayload, "expected full report to include the fenced JSON payload")
} finally {
await app.close().catch(() => undefined)
await closeApp(app)
rmSync(homeDir, { force: true, maxRetries: 5, recursive: true, retryDelay: 100 })
}
2 changes: 2 additions & 0 deletions packages/opencode/test/session/prompt-effect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ function makeHttp(httpLayer: Layer.Layer<HttpClient.HttpClient> = FetchHttpClien
// setup; default the live() timeout instead of bandaging individual tests.
// An explicit third-arg timeout still overrides.
const defaultLiveTimeout = process.platform === "win32" ? 10_000 : 3_000
const slowWindowsLiveTimeout = process.platform === "win32" ? 30_000 : undefined

function withDefaultLiveTimeout<
T extends { live: ((...args: any[]) => any) & { only: any; skip: any } },
Expand Down Expand Up @@ -1049,6 +1050,7 @@ it.live("loop gate records same-step repeated tool errors without block or stop"
}),
{ git: true, config: providerCfg },
),
slowWindowsLiveTimeout,
)

it.live("loop gate blocks repeated tool errors across model steps", () =>
Expand Down