Open existing agents from links and the CLI (#2324)

* feat(desktop): open existing agents from links

Register a stable agent deep link and route it through the existing Desktop window. Add a matching CLI command that resolves the local server and activates the requested agent without creating or messaging it.

* fix(desktop): recover agent link delivery
This commit is contained in:
Mohamed Boudra
2026-07-22 18:31:12 +02:00
committed by GitHub
parent 9952615c33
commit 76a5edb020
18 changed files with 504 additions and 42 deletions
+29 -24
View File
@@ -2,6 +2,7 @@ import { existsSync } from "node:fs";
import { homedir } from "node:os";
import path from "node:path";
import { spawnProcess } from "@getpaseo/server";
import { buildAgentDeepLink, type AgentDeepLinkTarget } from "@getpaseo/protocol/agent-deep-link";
function findDesktopApp(): string | null {
if (process.platform === "darwin") {
@@ -67,35 +68,39 @@ function spawnDetached(command: string, args: string[]): void {
}).unref();
}
function launchDesktop(args: string[]): void {
if (process.env.PASEO_DESKTOP_CLI === "1") {
throw new Error("Cannot open Paseo Desktop while running in desktop CLI passthrough mode.");
}
const desktopApp = findDesktopApp();
if (!desktopApp) {
throw new Error(
"Paseo desktop app not found. Install it from https://github.com/getpaseo/paseo/releases",
);
}
if (process.platform === "darwin") {
// -n forces a new instance even if the app is already running. The new
// instance relays its argv to the existing one through Electron's
// single-instance lock. -g keeps the terminal in the foreground.
spawnDetached("open", ["-n", "-g", "-a", desktopApp, "--args", ...args]);
return;
}
spawnDetached(desktopApp, args);
}
export async function openDesktopWithProject(projectPath: string): Promise<void> {
try {
if (process.env.PASEO_DESKTOP_CLI === "1") {
throw new Error(
"Cannot open a desktop project while running in desktop CLI passthrough mode.",
);
}
const desktopApp = findDesktopApp();
if (!desktopApp) {
throw new Error(
"Paseo desktop app not found. Install it from https://github.com/getpaseo/paseo/releases",
);
}
if (process.platform === "darwin") {
// -n forces a new instance even if the app is already running.
// The new instance hits requestSingleInstanceLock(), fails, and relays
// the argv to the first instance via the second-instance event.
// -g keeps the terminal in the foreground (better CLI UX).
// Without -n, macOS just activates the existing window and drops --args.
spawnDetached("open", ["-n", "-g", "-a", desktopApp, "--args", projectPath]);
return;
}
spawnDetached(desktopApp, [projectPath]);
launchDesktop([projectPath]);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
process.stderr.write(`${message}\n`);
process.exitCode = 1;
}
}
export async function openDesktopWithAgent(target: AgentDeepLinkTarget): Promise<void> {
launchDesktop([buildAgentDeepLink(target)]);
}