fix(switch-agent): use native tui.selectSession, use cross-platform symlink test target
This commit is contained in:
@@ -106,12 +106,18 @@ describe("athena-sisyphus-only hook", () => {
|
|||||||
expect(isAllowedPath(symlinkPath, tempWorkspaceRoot)).toBe(false)
|
expect(isAllowedPath(symlinkPath, tempWorkspaceRoot)).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#then rejects symlink inside .sisyphus/ pointing to /etc/passwd", async () => {
|
it("#then rejects symlink inside .sisyphus/ pointing to file outside workspace", async () => {
|
||||||
const symlinkPath = join(tempWorkspaceRoot, ".sisyphus", "passwd-link")
|
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 () => {
|
it("#then allows a regular file inside .sisyphus/tmp/", async () => {
|
||||||
|
|||||||
@@ -12,12 +12,8 @@ const DESCRIPTION =
|
|||||||
|
|
||||||
const ALLOWED_AGENTS = new Set<string>(SWITCHABLE_AGENT_NAMES)
|
const ALLOWED_AGENTS = new Set<string>(SWITCHABLE_AGENT_NAMES)
|
||||||
|
|
||||||
type TuiClient = {
|
type TuiService = {
|
||||||
post: (input: {
|
selectSession: (input?: { sessionID?: string }) => Promise<unknown>
|
||||||
url: string
|
|
||||||
body: { sessionID: string }
|
|
||||||
headers?: Record<string, string>
|
|
||||||
}) => Promise<unknown>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SessionClient = {
|
type SessionClient = {
|
||||||
@@ -52,24 +48,20 @@ function extractSessionId(response: unknown): string | undefined {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasTuiClient(client: SessionClient): client is SessionClient & { _client: TuiClient } {
|
function hasTuiService(client: SessionClient): client is SessionClient & { tui: TuiService } {
|
||||||
const maybeClient = Reflect.get(client as object, "_client")
|
const maybeTui = Reflect.get(client as object, "tui")
|
||||||
if (typeof maybeClient !== "object" || maybeClient === null) {
|
if (typeof maybeTui !== "object" || maybeTui === null) {
|
||||||
return false
|
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> {
|
async function navigateTuiToSession(client: SessionClient, sessionID: string): Promise<boolean> {
|
||||||
if (!hasTuiClient(client)) {
|
if (!hasTuiService(client)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await client._client.post({
|
await client.tui.selectSession({ sessionID })
|
||||||
url: "/tui/select-session",
|
|
||||||
body: { sessionID },
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
})
|
|
||||||
return true
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user