diff --git a/src/hooks/athena-sisyphus-only/index.test.ts b/src/hooks/athena-sisyphus-only/index.test.ts index 2710d2f11..535b896cb 100644 --- a/src/hooks/athena-sisyphus-only/index.test.ts +++ b/src/hooks/athena-sisyphus-only/index.test.ts @@ -106,12 +106,18 @@ describe("athena-sisyphus-only hook", () => { expect(isAllowedPath(symlinkPath, tempWorkspaceRoot)).toBe(false) }) - it("#then rejects symlink inside .sisyphus/ pointing to /etc/passwd", async () => { - const symlinkPath = join(tempWorkspaceRoot, ".sisyphus", "passwd-link") + it("#then rejects symlink inside .sisyphus/ pointing to file outside workspace", async () => { + const outsideTarget = join(tmpdir(), "athena-outside-target.txt") + const symlinkPath = join(tempWorkspaceRoot, ".sisyphus", "outside-link") - await symlink("/etc/passwd", symlinkPath) + await writeFile(outsideTarget, "outside-content", "utf-8") + try { + await symlink(outsideTarget, symlinkPath) - expect(isAllowedPath(symlinkPath, tempWorkspaceRoot)).toBe(false) + expect(isAllowedPath(symlinkPath, tempWorkspaceRoot)).toBe(false) + } finally { + await rm(outsideTarget, { force: true }) + } }) it("#then allows a regular file inside .sisyphus/tmp/", async () => { diff --git a/src/tools/switch-agent/tools.ts b/src/tools/switch-agent/tools.ts index 76dbe2878..a5225f47a 100644 --- a/src/tools/switch-agent/tools.ts +++ b/src/tools/switch-agent/tools.ts @@ -12,12 +12,8 @@ const DESCRIPTION = const ALLOWED_AGENTS = new Set(SWITCHABLE_AGENT_NAMES) -type TuiClient = { - post: (input: { - url: string - body: { sessionID: string } - headers?: Record - }) => Promise +type TuiService = { + selectSession: (input?: { sessionID?: string }) => Promise } type SessionClient = { @@ -52,24 +48,20 @@ function extractSessionId(response: unknown): string | undefined { return undefined } -function hasTuiClient(client: SessionClient): client is SessionClient & { _client: TuiClient } { - const maybeClient = Reflect.get(client as object, "_client") - if (typeof maybeClient !== "object" || maybeClient === null) { +function hasTuiService(client: SessionClient): client is SessionClient & { tui: TuiService } { + const maybeTui = Reflect.get(client as object, "tui") + if (typeof maybeTui !== "object" || maybeTui === null) { return false } - return typeof Reflect.get(maybeClient, "post") === "function" + return typeof Reflect.get(maybeTui, "selectSession") === "function" } async function navigateTuiToSession(client: SessionClient, sessionID: string): Promise { - if (!hasTuiClient(client)) { + if (!hasTuiService(client)) { return false } try { - await client._client.post({ - url: "/tui/select-session", - body: { sessionID }, - headers: { "Content-Type": "application/json" }, - }) + await client.tui.selectSession({ sessionID }) return true } catch { return false