fix: add missing run_in_background to resume snippet and fix background launch detection

This commit is contained in:
YeonGyu-Kim
2026-03-31 17:02:56 -07:00
parent 9f2c4500e8
commit 87445a2ef3
4 changed files with 115 additions and 1 deletions
@@ -0,0 +1,98 @@
/// <reference types="bun-types" />
import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test"
import { existsSync, mkdirSync, rmSync } from "node:fs"
import { tmpdir } from "node:os"
import { join } from "node:path"
import type { PluginInput } from "@opencode-ai/plugin"
import { createOpencodeClient, type Project } from "@opencode-ai/sdk"
const isCallerOrchestratorMock = mock(async () => true)
const collectGitDiffStatsMock = mock(() => {
throw new Error("background launches should not trigger verification")
})
mock.module("../../shared/session-utils", () => ({
isCallerOrchestrator: isCallerOrchestratorMock,
}))
mock.module("../../shared/git-worktree", () => ({
collectGitDiffStats: collectGitDiffStatsMock,
formatFileChanges: mock(() => "No file changes"),
}))
const { createToolExecuteAfterHandler } = await import("./tool-execute-after")
describe("createToolExecuteAfterHandler background launch detection", () => {
let testDirectory = ""
beforeEach(() => {
testDirectory = join(tmpdir(), `atlas-background-launch-${crypto.randomUUID()}`)
if (!existsSync(testDirectory)) {
mkdirSync(testDirectory, { recursive: true })
}
isCallerOrchestratorMock.mockClear()
collectGitDiffStatsMock.mockClear()
})
afterEach(() => {
if (testDirectory && existsSync(testDirectory)) {
rmSync(testDirectory, { recursive: true, force: true })
}
})
function createHandler() {
const project = {
id: "project-1",
worktree: testDirectory,
time: {
created: Date.now(),
},
} satisfies Project
const ctx = {
client: createOpencodeClient(),
project,
directory: testDirectory,
worktree: testDirectory,
serverUrl: new URL("https://example.com"),
$: Bun.$,
} satisfies PluginInput
return createToolExecuteAfterHandler({
ctx,
pendingFilePaths: new Map(),
pendingTaskRefs: new Map(),
autoCommit: true,
getState: () => ({ promptFailureCount: 0 }),
})
}
describe("#given a call_omo_agent background launch result", () => {
describe("#when tool.execute.after handles it", () => {
it("#then it should treat the launch as still running", async () => {
const handler = createHandler()
const output = {
title: "call_omo_agent",
output: "Background agent task launched successfully.",
metadata: {
sessionId: "ses_child123",
},
}
await handler(
{
tool: "call_omo_agent",
sessionID: "ses_parent",
},
output,
)
expect(output.output).toBe("Background agent task launched successfully.")
expect(collectGitDiffStatsMock).not.toHaveBeenCalled()
})
})
})
})
+1
View File
@@ -118,6 +118,7 @@ export function createToolExecuteAfterHandler(input: {
}
const isBackgroundLaunch = outputStr.includes("Background task launched") || outputStr.includes("Background task continued")
|| outputStr.includes("Background delegate launched")
|| outputStr.includes("Background agent task launched")
if (isBackgroundLaunch) {
return
}
+1 -1
View File
@@ -30,7 +30,7 @@ export function createTaskResumeInfoHook() {
output.output =
outputText.trimEnd() +
`\n\nto continue: task(session_id="${sessionId}", load_skills=[], prompt="...")`
`\n\nto continue: task(session_id="${sessionId}", load_skills=[], run_in_background=false, prompt="...")`
}
return {
+15
View File
@@ -1,3 +1,5 @@
/// <reference types="bun-types" />
import { describe, it, expect } from "bun:test"
import { createTaskResumeInfoHook } from "./index"
@@ -60,6 +62,19 @@ describe("createTaskResumeInfoHook", () => {
expect(output.output).toContain("to continue:")
expect(output.output).toContain("ses_abc123")
})
it("#then should include run_in_background in resume info", async () => {
const input = createInput("call_omo_agent")
const output = {
title: "delegate_task",
output: "Task completed.\nSession ID: ses_abc123",
metadata: {},
}
await afterHook(input, output)
expect(output.output).toContain("run_in_background=false")
})
})
})