Skip to content

Commit 08faeb3

Browse files
fix(opencode): answer subagent permissions in run (anomalyco#43675)
Co-authored-by: rekram1-node <[email protected]>
1 parent 5e75e5e commit 08faeb3

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

‎packages/opencode/src/cli/cmd/run.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,9 +696,14 @@ export const RunCommand = effectCmd({
696696
// created, and replies issued from inside the loop must use that client.
697697
async function loop(client: OpencodeClient, events: Awaited<ReturnType<typeof sdk.event.subscribe>>) {
698698
const toggles = new Map<string, boolean>()
699+
const sessions = new Set([sessionID])
699700
let error: string | undefined
700701

701702
for await (const event of events.stream) {
703+
if (event.type === "session.created" && event.properties.info.parentID) {
704+
if (sessions.has(event.properties.info.parentID)) sessions.add(event.properties.info.id)
705+
}
706+
702707
if (
703708
event.type === "message.updated" &&
704709
event.properties.sessionID === sessionID &&
@@ -795,7 +800,7 @@ export const RunCommand = effectCmd({
795800

796801
if (event.type === "permission.asked") {
797802
const permission = event.properties
798-
if (permission.sessionID !== sessionID) continue
803+
if (!sessions.has(permission.sessionID)) continue
799804

800805
if (auto) {
801806
await client.permission.reply({

‎packages/opencode/test/cli/run/run-process.test.ts‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,50 @@ describe("opencode run (non-interactive subprocess)", () => {
277277
60_000,
278278
)
279279

280+
cliIt.concurrent(
281+
"answers requested permissions from subagents",
282+
({ llm, opencode }) =>
283+
Effect.gen(function* () {
284+
yield* llm.tool("task", {
285+
description: "Run a command",
286+
prompt: "Run the requested command",
287+
subagent_type: "general",
288+
})
289+
yield* llm.tool("bash", { command: "printf child", description: "Print from the child" })
290+
yield* llm.text("child finished")
291+
yield* llm.text("parent finished")
292+
293+
const result = yield* opencode.run("delegate a command", {
294+
permission: { bash: "ask" },
295+
extraArgs: ["--dangerously-skip-permissions"],
296+
timeoutMs: 10_000,
297+
})
298+
299+
opencode.expectExit(result, 0)
300+
expect(result.stdout).toContain("parent finished")
301+
302+
yield* llm.reset
303+
yield* llm.tool("task", {
304+
description: "Run a command",
305+
prompt: "Run the requested command",
306+
subagent_type: "general",
307+
})
308+
yield* llm.tool("bash", { command: "printf child", description: "Print from the child" })
309+
yield* llm.text("child continued")
310+
yield* llm.text("parent continued")
311+
312+
const rejected = yield* opencode.run("delegate a rejected command", {
313+
permission: { bash: "ask" },
314+
timeoutMs: 10_000,
315+
})
316+
317+
opencode.expectExit(rejected, 0)
318+
expect(rejected.stderr).toContain("permission requested: bash")
319+
expect(rejected.stdout).toContain("child continued")
320+
}),
321+
30_000,
322+
)
323+
280324
cliIt.live(
281325
"attach mode sends client-local file contents without a shared path",
282326
({ home, llm, opencode }) =>

0 commit comments

Comments
 (0)