Fix desktop CLI passthrough tty handling (#791)

* Fix desktop CLI passthrough tty handling

* Fix desktop daemon manager test drift

* Update daemon stop test after main merge

* test(cli): isolate npx cache per CLI test
This commit is contained in:
Mohamed Boudra
2026-05-07 15:14:18 +08:00
committed by GitHub
parent 6fb2fe2283
commit faf664d803
20 changed files with 868 additions and 461 deletions
+20 -17
View File
@@ -1,9 +1,10 @@
process.emitWarning = (() => {}) as typeof process.emitWarning;
import log from "electron-log/main";
log.transports.console.level = "info";
log.initialize({ spyRendererConsole: true });
import { inheritLoginShellEnv } from "./login-shell-env.js";
inheritLoginShellEnv();
import path from "node:path";
import { pathToFileURL } from "node:url";
@@ -11,10 +12,7 @@ import { existsSync } from "node:fs";
import { execFileSync } from "node:child_process";
import { app, BrowserWindow, Menu, ipcMain, nativeImage, net, protocol, session } from "electron";
import { createDaemonCommandHandlers, registerDaemonManager } from "./daemon/daemon-manager.js";
import {
parseCliPassthroughArgsFromArgv,
runCliPassthroughCommand,
} from "./daemon/runtime-paths.js";
import { parsePassthroughCliArgsFromArgv, runPassthroughCli } from "./daemon/cli/passthrough.js";
import { closeAllTransportSessions } from "./daemon/local-transport.js";
import {
registerWindowManager,
@@ -51,9 +49,11 @@ import {
stopDesktopManagedDaemonOnQuitIfNeeded,
} from "./daemon/quit-lifecycle.js";
import { autoUpdateSkillsIfInstalled } from "./integrations/integrations-manager.js";
import { runDesktopStartup } from "./desktop-startup.js";
const DEV_SERVER_URL = process.env.EXPO_DEV_URL ?? "http://localhost:8081";
const APP_SCHEME = "paseo";
const PASEO_DEBUG = process.env.PASEO_DEBUG === "1";
function isAllowedBrowserWebviewUrl(value: string | undefined): boolean {
if (!value) {
@@ -241,9 +241,11 @@ let pendingOpenProjectPath = parseOpenProjectPathFromArgv({
isDefaultApp: process.defaultApp,
});
log.info("[open-project] argv:", process.argv);
log.info("[open-project] isDefaultApp:", process.defaultApp);
log.info("[open-project] pendingOpenProjectPath:", pendingOpenProjectPath);
if (PASEO_DEBUG) {
log.info("[open-project] argv:", process.argv);
log.info("[open-project] isDefaultApp:", process.defaultApp);
log.info("[open-project] pendingOpenProjectPath:", pendingOpenProjectPath);
}
// The renderer pulls the pending path on mount via IPC — this avoids
// a race where the push event arrives before React registers its listener.
@@ -549,18 +551,18 @@ function setupSingleInstanceLock(): boolean {
}
async function runCliPassthroughIfRequested(): Promise<boolean> {
const cliArgs = parseCliPassthroughArgsFromArgv(process.argv);
const cliArgs = parsePassthroughCliArgsFromArgv(process.argv);
if (!cliArgs) {
return false;
}
try {
const exitCode = runCliPassthroughCommand(cliArgs);
process.exit(exitCode);
const exitCode = await runPassthroughCli(cliArgs);
app.exit(exitCode);
} catch (error) {
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
process.stderr.write(`${message}\n`);
process.exit(1);
app.exit(1);
}
return true;
@@ -614,10 +616,6 @@ function waitForDesktopSmokeStopRequest(): Promise<void> {
}
async function bootstrap(): Promise<void> {
if (!pendingOpenProjectPath && (await runCliPassthroughIfRequested())) {
return;
}
if (!setupSingleInstanceLock()) {
return;
}
@@ -676,7 +674,12 @@ async function bootstrap(): Promise<void> {
});
}
void bootstrap().catch((error) => {
void runDesktopStartup({
hasPendingOpenProjectPath: Boolean(pendingOpenProjectPath),
runCliPassthroughIfRequested,
inheritLoginShellEnv,
bootstrapGui: bootstrap,
}).catch((error) => {
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
process.stderr.write(`${message}\n`);
process.exit(1);