mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-19 02:23:30 +00:00
fix(tui): restore permissions on reconnect
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
This commit is contained in:
parent
5db320b02d
commit
52ad916ba4
3 changed files with 58 additions and 0 deletions
|
|
@ -1064,6 +1064,16 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({
|
|||
)
|
||||
for (const session of response.data) registerSession(session.id)
|
||||
}),
|
||||
sdk.api.permission.listRequests({ location: locationQuery(defaultLocation()) }).then((response) => {
|
||||
const permissions = mutable(response.data).reduce<Record<string, PermissionV2Request[]>>(
|
||||
(result, request) => ({
|
||||
...result,
|
||||
[request.sessionID]: [...(result[request.sessionID] ?? []), request],
|
||||
}),
|
||||
{},
|
||||
)
|
||||
setStore("session", "permission", reconcile(permissions))
|
||||
}),
|
||||
result.location.refresh(),
|
||||
result.location.agent.refresh(),
|
||||
result.location.integration.refresh(),
|
||||
|
|
|
|||
|
|
@ -1521,6 +1521,52 @@ test("adds and dismisses permission requests from live events", async () => {
|
|||
}
|
||||
})
|
||||
|
||||
test("reconciles all pending permission requests when the event stream reconnects", async () => {
|
||||
const events = createEventStream()
|
||||
let requests = [
|
||||
{ id: "per_old", sessionID: "ses_old", action: "read", resources: ["old.txt"] },
|
||||
{ id: "per_keep", sessionID: "ses_keep", action: "shell", resources: ["bun test"] },
|
||||
]
|
||||
let calls = 0
|
||||
const fetch = createFetch((url) => {
|
||||
if (url.pathname !== "/api/permission/request") return
|
||||
calls++
|
||||
return json({ location: { directory, project: { id: "proj_test", directory } }, data: requests })
|
||||
}, events)
|
||||
let data!: ReturnType<typeof useData>
|
||||
|
||||
function Probe() {
|
||||
data = useData()
|
||||
return <box />
|
||||
}
|
||||
|
||||
const app = await testRender(() => (
|
||||
<TestTuiContexts>
|
||||
<SDKProvider client={createClient(fetch.fetch)} api={createApi(fetch.fetch)}>
|
||||
<ProjectProvider>
|
||||
<DataProvider>
|
||||
<Probe />
|
||||
</DataProvider>
|
||||
</ProjectProvider>
|
||||
</SDKProvider>
|
||||
</TestTuiContexts>
|
||||
))
|
||||
|
||||
try {
|
||||
await wait(() => data.session.permission.list("ses_old")?.[0]?.id === "per_old")
|
||||
expect(data.session.permission.list("ses_keep")?.[0]?.id).toBe("per_keep")
|
||||
|
||||
requests = [{ id: "per_new", sessionID: "ses_new", action: "edit", resources: ["new.txt"] }]
|
||||
events.disconnect()
|
||||
|
||||
await wait(() => calls === 2 && data.session.permission.list("ses_new")?.[0]?.id === "per_new")
|
||||
expect(data.session.permission.list("ses_old")).toBeUndefined()
|
||||
expect(data.session.permission.list("ses_keep")).toBeUndefined()
|
||||
} finally {
|
||||
app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("adds, dismisses, and refreshes form requests", async () => {
|
||||
const events = createEventStream()
|
||||
const calls = createFetch((url) => {
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ export function createFetch(override?: FetchHandler, events?: ReturnType<typeof
|
|||
return json({ location: { directory, project: { id: "proj_test", directory: worktree } }, data: [] })
|
||||
if (url.pathname === "/api/session") return json({ data: [], cursor: {} })
|
||||
if (url.pathname === "/api/session/active") return json({ data: {} })
|
||||
if (url.pathname === "/api/permission/request")
|
||||
return json({ location: { directory, project: { id: "proj_test", directory: worktree } }, data: [] })
|
||||
if (/^\/api\/session\/[^/]+\/form$/.test(url.pathname)) return json({ data: [] })
|
||||
if (
|
||||
["/api/agent", "/api/model", "/api/provider", "/api/integration", "/api/command", "/api/skill"].includes(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue