fix(opencode): answer subagent permissions in run (#43675)

Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot] 2026-08-20 19:29:32 -05:00 committed by GitHub
parent 5e75e5e990
commit 08faeb3893
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 1 deletions

View file

@ -696,9 +696,14 @@ export const RunCommand = effectCmd({
// created, and replies issued from inside the loop must use that client.
async function loop(client: OpencodeClient, events: Awaited<ReturnType<typeof sdk.event.subscribe>>) {
const toggles = new Map<string, boolean>()
const sessions = new Set([sessionID])
let error: string | undefined
for await (const event of events.stream) {
if (event.type === "session.created" && event.properties.info.parentID) {
if (sessions.has(event.properties.info.parentID)) sessions.add(event.properties.info.id)
}
if (
event.type === "message.updated" &&
event.properties.sessionID === sessionID &&
@ -795,7 +800,7 @@ export const RunCommand = effectCmd({
if (event.type === "permission.asked") {
const permission = event.properties
if (permission.sessionID !== sessionID) continue
if (!sessions.has(permission.sessionID)) continue
if (auto) {
await client.permission.reply({

View file

@ -277,6 +277,50 @@ describe("opencode run (non-interactive subprocess)", () => {
60_000,
)
cliIt.concurrent(
"answers requested permissions from subagents",
({ llm, opencode }) =>
Effect.gen(function* () {
yield* llm.tool("task", {
description: "Run a command",
prompt: "Run the requested command",
subagent_type: "general",
})
yield* llm.tool("bash", { command: "printf child", description: "Print from the child" })
yield* llm.text("child finished")
yield* llm.text("parent finished")
const result = yield* opencode.run("delegate a command", {
permission: { bash: "ask" },
extraArgs: ["--dangerously-skip-permissions"],
timeoutMs: 10_000,
})
opencode.expectExit(result, 0)
expect(result.stdout).toContain("parent finished")
yield* llm.reset
yield* llm.tool("task", {
description: "Run a command",
prompt: "Run the requested command",
subagent_type: "general",
})
yield* llm.tool("bash", { command: "printf child", description: "Print from the child" })
yield* llm.text("child continued")
yield* llm.text("parent continued")
const rejected = yield* opencode.run("delegate a rejected command", {
permission: { bash: "ask" },
timeoutMs: 10_000,
})
opencode.expectExit(rejected, 0)
expect(rejected.stderr).toContain("permission requested: bash")
expect(rejected.stdout).toContain("child continued")
}),
30_000,
)
cliIt.live(
"attach mode sends client-local file contents without a shared path",
({ home, llm, opencode }) =>