import { afterEach, describe, expect, test, vi } from "vitest"; import type { SubagentDetectionContext } from "#src/authority/subagent-context"; import { SubagentDetection } from "#src/authority/subagent-detection"; import { SubagentSessionRegistry } from "#src/authority/subagent-registry"; import { posixPathFlavor } from "#src/path/path-flavor"; afterEach(() => { vi.unstubAllEnvs(); vi.restoreAllMocks(); }); function makeCtx( sessionDir: string | null, sessionId: string = "", ): SubagentDetectionContext { return { sessionManager: { getSessionDir: vi.fn(() => sessionDir ?? ""), getSessionId: vi.fn(() => sessionId), }, }; } const subagentSessionsDir = "/agent/subagent-sessions"; describe("SubagentDetection", () => { describe("isSubagent", () => { test("returns true for a registered in-process child (registry source)", () => { const registry = new SubagentSessionRegistry(); registry.register("child-1", {}); const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry, }); expect(detection.isSubagent(makeCtx(null, "child-1"))).toBe(true); }); test("returns true when a subagent env hint is set (env source)", () => { vi.stubEnv("PI_IS_SUBAGENT", "1"); const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry: new SubagentSessionRegistry(), }); expect(detection.isSubagent(makeCtx("/somewhere/else"))).toBe(true); }); test("returns true when the session dir is nested under subagentSessionsDir (filesystem source)", () => { const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry: new SubagentSessionRegistry(), }); expect( detection.isSubagent(makeCtx(`${subagentSessionsDir}/child-1`)), ).toBe(true); }); test("returns false when no source matches", () => { const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry: new SubagentSessionRegistry(), }); expect(detection.isSubagent(makeCtx("/projects/my-app"))).toBe(false); }); }); describe("isRegisteredChild", () => { test("returns true when the session id is registered", () => { const registry = new SubagentSessionRegistry(); registry.register("child-1", {}); const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry, }); expect(detection.isRegisteredChild(makeCtx(null, "child-1"))).toBe(true); }); test("returns false when the session id is not registered", () => { const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, registry: new SubagentSessionRegistry(), }); expect(detection.isRegisteredChild(makeCtx(null, "child-1"))).toBe(false); }); test("returns false when constructed without a registry", () => { const detection = new SubagentDetection({ subagentSessionsDir, flavor: posixPathFlavor, }); expect(detection.isRegisteredChild(makeCtx(null, "child-1"))).toBe(false); }); }); });