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
+5
View File
@@ -14,6 +14,7 @@ import { addReloadOptions, runReloadCommand } from "./reload.js";
import { addImportOptions, runImportCommand } from "./import.js";
import { runUpdateCommand } from "./update.js";
import { runDetachCommand } from "./detach.js";
import { addOpenOptions, runOpenCommand } from "./open.js";
import { withOutput } from "../../output/index.js";
import {
addDaemonHostOption,
@@ -39,6 +40,10 @@ export function createAgentCommand(): Command {
addDaemonHostOption(addLogsOptions(agent.command("logs"))).action(runLogsCommand);
addJsonAndDaemonHostOptions(addOpenOptions(agent.command("open"))).action(
withOutput(runOpenCommand),
);
addJsonAndDaemonHostOptions(addStopOptions(agent.command("stop"))).action(
withOutput(runStopCommand),
);
+82
View File
@@ -0,0 +1,82 @@
import type { Command } from "commander";
import { buildDaemonConnectionCommandError, connectToDaemon } from "../../utils/client.js";
import { openDesktopWithAgent } from "../open.js";
import type {
CommandError,
CommandOptions,
OutputSchema,
SingleResult,
} from "../../output/index.js";
interface OpenAgentResult {
agentId: string;
serverId: string;
status: "opened";
}
const openAgentSchema: OutputSchema<OpenAgentResult> = {
idField: "agentId",
columns: [
{ header: "AGENT ID", field: "agentId" },
{ header: "SERVER ID", field: "serverId" },
{ header: "STATUS", field: "status" },
],
};
export function addOpenOptions(command: Command): Command {
return command
.description("Open an existing agent in Paseo Desktop")
.argument("<agent-id>", "Existing agent ID")
.option("--server <server-id>", "Server ID (defaults to the local daemon)");
}
async function resolveServerId(options: CommandOptions): Promise<string> {
const explicitServerId = typeof options.server === "string" ? options.server.trim() : "";
if (explicitServerId) {
return explicitServerId;
}
let client;
try {
client = await connectToDaemon({ host: options.host });
} catch (error) {
throw buildDaemonConnectionCommandError({ host: options.host, error });
}
try {
const serverId = client.getLastServerInfoMessage()?.serverId.trim();
if (!serverId) {
const error: CommandError = {
code: "SERVER_ID_UNAVAILABLE",
message: "The daemon did not report a server ID.",
};
throw error;
}
return serverId;
} finally {
await client.close().catch(() => {});
}
}
export async function runOpenCommand(
agentIdArg: string,
options: CommandOptions,
_command: Command,
): Promise<SingleResult<OpenAgentResult>> {
const agentId = agentIdArg.trim();
if (!agentId) {
const error: CommandError = {
code: "MISSING_AGENT_ID",
message: "Agent ID is required.",
};
throw error;
}
const serverId = await resolveServerId(options);
await openDesktopWithAgent({ serverId, agentId });
return {
type: "single",
data: { agentId, serverId, status: "opened" },
schema: openAgentSchema,
};
}