fix(switch-agent): use native tui.selectSession, use cross-platform symlink test target

This commit is contained in:
ismeth
2026-03-14 18:51:00 +01:00
committed by YeonGyu-Kim
parent 68cd8814d8
commit 37f03b4238
2 changed files with 18 additions and 20 deletions
+10 -4
View File
@@ -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 () => {
+8 -16
View File
@@ -12,12 +12,8 @@ const DESCRIPTION =
const ALLOWED_AGENTS = new Set<string>(SWITCHABLE_AGENT_NAMES)
type TuiClient = {
post: (input: {
url: string
body: { sessionID: string }
headers?: Record<string, string>
}) => Promise<unknown>
type TuiService = {
selectSession: (input?: { sessionID?: string }) => Promise<unknown>
}
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<boolean> {
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