feat(desktop): add daemon status dialog to built-in daemon settings

Add a "Full status" button in the desktop daemon section that runs
`paseo daemon status` via Electron IPC and displays the raw output
in a modal.

Also fixes Commander.js argv parsing when the CLI is invoked via
Electron's ELECTRON_RUN_AS_NODE — Commander auto-detects the Electron
environment and skips only 1 argv element instead of 2, causing
"unknown command" errors. Fixed by explicitly passing { from: "node" }.
This commit is contained in:
Mohamed Boudra
2026-04-03 18:49:59 +07:00
parent f924d33076
commit 4ca04fc661
5 changed files with 106 additions and 1 deletions
@@ -21,6 +21,7 @@ import {
createNodeEntrypointInvocation,
resolveDaemonRunnerEntrypoint,
runCliJsonCommand,
runCliTextCommand,
} from "./runtime-paths.js";
const DAEMON_LOG_FILENAME = "daemon.log";
@@ -398,6 +399,10 @@ function getDaemonLogs(): DesktopDaemonLogs {
};
}
function getCliDaemonStatus(): string {
return runCliTextCommand(["daemon", "status"]);
}
async function getDaemonPairing(): Promise<DesktopPairingOffer> {
const status = resolveStatus();
if (status.status !== "running") {
@@ -521,6 +526,7 @@ export function createDaemonCommandHandlers(): Record<string, DesktopCommandHand
desktop_daemon_logs: () => getDaemonLogs(),
desktop_daemon_pairing: () => getDaemonPairing(),
cli_symlink_instructions: () => getCliSymlinkInstructions(),
cli_daemon_status: () => getCliDaemonStatus(),
write_attachment_base64: (args) => writeAttachmentBase64(args ?? {}),
copy_attachment_file: (args) => copyAttachmentFileToManagedStorage(args ?? {}),
read_file_base64: (args) => readManagedFileBase64(args ?? {}),
@@ -246,6 +246,26 @@ export function runCliPassthroughCommand(args: string[]): number {
return result.signal ? 1 : 0;
}
export function runCliTextCommand(args: string[]): string {
const invocation = createCliInvocation(args);
const result = spawnSync(invocation.command, invocation.args, {
env: invocation.env,
encoding: "utf-8",
stdio: ["ignore", "pipe", "pipe"],
});
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
throw new Error(stderr.length > 0 ? stderr : `CLI command failed with exit code ${result.status}`);
}
return typeof result.stdout === "string" ? result.stdout.trimEnd() : "";
}
export function runCliJsonCommand(args: string[]): unknown {
const invocation = createCliInvocation(args);
const result = spawnSync(invocation.command, invocation.args, {