From b6a1984cba53fdd104af5e1a3840d11742894e4d Mon Sep 17 00:00:00 2001 From: imMxts Date: Sun, 16 Aug 2026 22:43:42 +0200 Subject: [PATCH 1/2] fix(desktop): --version segfaults without a display Headless `t3code --version` walked DesktopApp.startup into ElectronApp.whenReady, so Ozone crashed before any version printed. Match whole-token --version/-V in isVersionRequest and print+exit in main.ts before DesktopApp.program. Implemented with grok-4.5 in T3 Code. --- apps/desktop/src/app/DesktopPreReadyPlatform.test.ts | 10 ++++++++++ apps/desktop/src/app/DesktopPreReadyPlatform.ts | 4 ++++ apps/desktop/src/main.ts | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts index a29e0fd3baf..ceb81ff09c1 100644 --- a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts +++ b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts @@ -78,6 +78,16 @@ describe("DesktopPreReadyPlatform", () => { assert.isNull(value); }); + it("detects --version and -V as whole-token version requests", () => { + assert.isTrue(DesktopPreReadyPlatform.isVersionRequest(["--version"])); + assert.isTrue(DesktopPreReadyPlatform.isVersionRequest(["-V"])); + assert.isFalse(DesktopPreReadyPlatform.isVersionRequest(["--no-sandbox"])); + assert.isFalse(DesktopPreReadyPlatform.isVersionRequest(["--version=1"])); + assert.isFalse(DesktopPreReadyPlatform.isVersionRequest(["--version-foo"])); + assert.isFalse(DesktopPreReadyPlatform.isVersionRequest(["-v"])); + assert.isFalse(DesktopPreReadyPlatform.isVersionRequest([])); + }); + it.effect( "acquires a synchronous pre-ready layer before an asynchronous Clerk-shaped layer", () => diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.ts index 7d145632d0b..cf5eb5c11a5 100644 --- a/apps/desktop/src/app/DesktopPreReadyPlatform.ts +++ b/apps/desktop/src/app/DesktopPreReadyPlatform.ts @@ -29,6 +29,10 @@ export function readCommandLineSwitchValue( return value.length > 0 ? value : null; } +export function isVersionRequest(argv: ReadonlyArray): boolean { + return argv.includes("--version") || argv.includes("-V"); +} + export const resolveEarlyLinuxElectronOptionsFromProcess = (): DesktopEarlyElectronStartup.EarlyLinuxElectronOptions => DesktopEarlyElectronStartup.resolveEarlyLinuxElectronOptions({ diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 14caeed8a9a..107e580cdb1 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -216,4 +216,10 @@ const desktopRuntimeLayer = desktopClerkLayer.pipe( Layer.provideMerge(DesktopPreReadyPlatform.layer), ); +if (DesktopPreReadyPlatform.isVersionRequest(process.argv)) { + // @effect-diagnostics-next-line globalConsole:off - print and exit before the Effect runtime exists. + console.log(Electron.app.getVersion()); + process.exit(0); +} + DesktopApp.program.pipe(Effect.provide(desktopRuntimeLayer), NodeRuntime.runMain); From 69817a1c8d66e9ef219c1f9388f0e66ce0f88095 Mon Sep 17 00:00:00 2001 From: imMxts Date: Sun, 16 Aug 2026 23:01:49 +0200 Subject: [PATCH 2/2] fix(desktop): flush --version before hard exit console.log then process.exit can drop piped stdout on Electron before whenReady. writeStdoutLineSync writes fd 1, swallows EPIPE, then main still process.exit(0). Implemented with grok-4.6 in T3 Code. --- .../src/app/DesktopPreReadyPlatform.test.ts | 21 +++++++++++++++++++ .../src/app/DesktopPreReadyPlatform.ts | 14 +++++++++++++ apps/desktop/src/main.ts | 3 +-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts index ceb81ff09c1..6e8d597c692 100644 --- a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts +++ b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts @@ -88,6 +88,27 @@ describe("DesktopPreReadyPlatform", () => { assert.isFalse(DesktopPreReadyPlatform.isVersionRequest([])); }); + it("writes a version line to stdout synchronously and swallows EPIPE", () => { + const writes: Array<{ fd: number; data: string }> = []; + DesktopPreReadyPlatform.writeStdoutLineSync("1.2.3", (fd, data) => { + writes.push({ fd, data }); + }); + assert.deepEqual(writes, [{ fd: 1, data: "1.2.3\n" }]); + + DesktopPreReadyPlatform.writeStdoutLineSync("1.2.3", () => { + throw Object.assign(new Error("broken pipe"), { code: "EPIPE" }); + }); + + try { + DesktopPreReadyPlatform.writeStdoutLineSync("1.2.3", () => { + throw Object.assign(new Error("bad fd"), { code: "EBADF" }); + }); + assert.fail("expected EBADF to propagate"); + } catch (error) { + assert.equal((error as NodeJS.ErrnoException).code, "EBADF"); + } + }); + it.effect( "acquires a synchronous pre-ready layer before an asynchronous Clerk-shaped layer", () => diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.ts index cf5eb5c11a5..f4014b38b4b 100644 --- a/apps/desktop/src/app/DesktopPreReadyPlatform.ts +++ b/apps/desktop/src/app/DesktopPreReadyPlatform.ts @@ -33,6 +33,20 @@ export function isVersionRequest(argv: ReadonlyArray): boolean { return argv.includes("--version") || argv.includes("-V"); } +export function writeStdoutLineSync( + line: string, + writeSync: (fd: number, data: string) => void = (fd, data) => { + NodeFS.writeSync(fd, data); + }, +): void { + try { + writeSync(1, `${line}\n`); + } catch (error) { + const err = error as NodeJS.ErrnoException; + if (err.code !== "EPIPE") throw error; + } +} + export const resolveEarlyLinuxElectronOptionsFromProcess = (): DesktopEarlyElectronStartup.EarlyLinuxElectronOptions => DesktopEarlyElectronStartup.resolveEarlyLinuxElectronOptions({ diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 107e580cdb1..9fb08388384 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -217,8 +217,7 @@ const desktopRuntimeLayer = desktopClerkLayer.pipe( ); if (DesktopPreReadyPlatform.isVersionRequest(process.argv)) { - // @effect-diagnostics-next-line globalConsole:off - print and exit before the Effect runtime exists. - console.log(Electron.app.getVersion()); + DesktopPreReadyPlatform.writeStdoutLineSync(Electron.app.getVersion()); process.exit(0); }