Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions agent-identity/daemon-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ export function isDaemonRunning(socketPath: string = DEFAULT_SOCKET_PATH): boole
return existsSync(socketPath);
}

/**
* Resolve a --agent-name CLI flag value to a session file path.
*
* Returns null when the flag is unset, not a string, matches the current
* agent name, or the target agent isn't registered in the daemon.
*/
export async function resolveTargetSession(
flagValue: string | boolean | undefined,
currentAgentName: string,
socketPath: string = DEFAULT_SOCKET_PATH,
): Promise<string | null> {
if (!flagValue || typeof flagValue !== "string") return null;
if (flagValue === currentAgentName) return null;
return await queryDaemonForSession(flagValue, socketPath);
}

/**
* Query the daemon for an agent's session file path.
* Connects, sends lookup_agent, returns sessionFile or null.
Expand Down
16 changes: 15 additions & 1 deletion agent-identity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { createConnection, Socket } from "node:net";
import { existsSync, readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { isDaemonRunning } from "./daemon-client.ts";
import { isDaemonRunning, resolveTargetSession } from "./daemon-client.ts";

// ─── Name generation ────────────────────────────────────────────────────────

Expand Down Expand Up @@ -430,6 +430,20 @@ export default function (pi: ExtensionAPI) {
// Capture session file path
sessionFile = ctx.sessionManager.getSessionFile();

// ── Handle --agent-name flag: resolve and revive target session ──
const flagValue = pi.getFlag("agent-name");
const targetSession = await resolveTargetSession(flagValue, agentName);
if (targetSession) {
// Spawn a new pi process pointed at the target session, then exit.
// This mirrors the daemon's resumeSession behaviour.
spawn(
process.env["PI_CMD"] ?? "pi",
["--session", targetSession],
{ detached: true, stdio: "ignore", env: { ...process.env } },
).unref();
process.exit(0);
}

if (ctx.hasUI) {
ctx.ui.notify(`Agent identity: ${agentName}`, "info");
ctx.ui.setStatus("agent-identity", `🟡 ${agentName} (connecting to daemon...)`);
Expand Down
32 changes: 31 additions & 1 deletion test/agent-session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { describe, it, before, after } from "node:test";
import { strict as assert } from "node:assert";
import { createServer, Socket, Server } from "node:net";
import { existsSync, unlinkSync } from "node:fs";
import { queryDaemonForSession } from "../agent-identity/daemon-client.ts";
import { queryDaemonForSession, resolveTargetSession } from "../agent-identity/daemon-client.ts";

const SOCKET_PATH = "/tmp/agent-identity-daemon-test.sock";

Expand Down Expand Up @@ -104,4 +104,34 @@ describe("queryDaemonForSession without daemon", () => {
});
});

describe("resolveTargetSession", () => {
before(startMockDaemon);
after(stopMockDaemon);

it("returns null when flag is undefined", async () => {
const result = await resolveTargetSession(undefined, "polar-lemur-69", SOCKET_PATH);
assert.equal(result, null);
});

it("returns null when flag is not a string (boolean)", async () => {
const result = await resolveTargetSession(true, "polar-lemur-69", SOCKET_PATH);
assert.equal(result, null);
});

it("returns null when flag matches current agent name", async () => {
const result = await resolveTargetSession("solar-falcon-55", "solar-falcon-55", SOCKET_PATH);
assert.equal(result, null);
});

it("resolves session file when flag differs and agent exists in daemon", async () => {
const result = await resolveTargetSession("test-fox-42", "polar-lemur-69", SOCKET_PATH);
assert.equal(result, "/tmp/test-session.jsonl");
});

it("returns null when flag differs but agent not found in daemon", async () => {
const result = await resolveTargetSession("nonexistent-99", "polar-lemur-69", SOCKET_PATH);
assert.equal(result, null);
});
});


Loading