fix(delegate-task): start child prompts reliably

Preserve delegated child prompt/bootstrap metadata for early runtime fallback before OpenCode has persisted the first user turn. Bind prompt gate calls to the SDK session receiver and keep completed background task lookup visible across plugin manager instances.
This commit is contained in:
YeonGyu-Kim
2026-05-16 16:21:48 +09:00
parent 76e573a920
commit 982fa81367
11 changed files with 742 additions and 88 deletions
@@ -91,6 +91,36 @@ describe("promptAsyncAfterSessionIdle", () => {
expect(promptCalls).toBe(1)
})
test("#given SDK promptAsync depends on its session receiver #when the gate dispatches #then method binding is preserved", async () => {
// given
const session = {
_client: { accepted: true },
async promptAsync(
this: { _client: { accepted: boolean } },
input: { path: { id: string }, body: { parts: unknown[] } },
) {
return { accepted: this._client.accepted, sessionID: input.path.id }
},
}
const client = { session }
// when
const result = await promptAsyncAfterSessionIdle({
client,
sessionID: "ses_bound_prompt_async",
input: { path: { id: "ses_bound_prompt_async" }, body: { parts: [] } },
source: "test:bound-prompt-async",
settleMs: 0,
postDispatchHoldMs: 0,
})
// then
expect(result).toEqual({
status: "dispatched",
response: { accepted: true, sessionID: "ses_bound_prompt_async" },
})
})
test("#given session.status reports busy #when an internal promptAsync is requested #then no prompt is sent", async () => {
// given
let promptCalls = 0
@@ -445,4 +475,34 @@ describe("promptAsyncAfterSessionIdle", () => {
expect(second.status).toBe("reserved")
expect(promptCalls).toBe(1)
})
test("#given SDK prompt depends on its session receiver #when the gate dispatches #then method binding is preserved", async () => {
// given
const session = {
_client: { accepted: true },
async prompt(
this: { _client: { accepted: boolean } },
input: { path: { id: string }, body: { parts: unknown[] } },
) {
return { accepted: this._client.accepted, sessionID: input.path.id }
},
}
const client = { session }
// when
const result = await promptAfterSessionIdle({
client,
sessionID: "ses_bound_prompt",
input: { path: { id: "ses_bound_prompt" }, body: { parts: [] } },
source: "test:bound-prompt",
settleMs: 0,
postDispatchHoldMs: 0,
})
// then
expect(result).toEqual({
status: "dispatched",
response: { accepted: true, sessionID: "ses_bound_prompt" },
})
})
})