fix full-suite isolation regressions

This commit is contained in:
YeonGyu-Kim
2026-05-07 17:47:53 +09:00
parent 102b5f96e7
commit ee938aa097
62 changed files with 1238 additions and 899 deletions
+108 -119
View File
@@ -1,8 +1,9 @@
import { describe, expect, test, beforeEach, afterEach, mock, afterAll } from "bun:test"
import { describe, expect, test, beforeEach, afterEach, mock } from "bun:test"
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs"
import { join } from "node:path"
import { tmpdir } from "node:os"
import { randomUUID } from "node:crypto"
import { createOpencodeClient } from "@opencode-ai/sdk"
import {
writeBoulderState,
clearBoulderState,
@@ -10,35 +11,16 @@ import {
} from "../../features/boulder-state"
import type { BoulderState } from "../../features/boulder-state"
import { _resetForTesting, registerAgentName, subagentSessions, updateSessionAgent } from "../../features/claude-code-session-state"
import type { PendingTaskRef } from "./types"
import type { AtlasHookOptions, PendingTaskRef } from "./types"
import { createAtlasHook } from "./index"
import { createToolExecuteAfterHandler } from "./tool-execute-after"
import { createToolExecuteBeforeHandler } from "./tool-execute-before"
const TEST_STORAGE_ROOT = join(tmpdir(), `atlas-message-storage-${randomUUID()}`)
const TEST_MESSAGE_STORAGE = join(TEST_STORAGE_ROOT, "message")
const TEST_PART_STORAGE = join(TEST_STORAGE_ROOT, "part")
mock.module("../../features/hook-message-injector/constants", () => ({
OPENCODE_STORAGE: TEST_STORAGE_ROOT,
MESSAGE_STORAGE: TEST_MESSAGE_STORAGE,
PART_STORAGE: TEST_PART_STORAGE,
}))
mock.module("../../shared/opencode-message-dir", () => ({
getMessageDir: (sessionID: string) => {
const dir = join(TEST_MESSAGE_STORAGE, sessionID)
return existsSync(dir) ? dir : null
},
}))
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => false,
}))
afterAll(() => { mock.restore() })
const { createAtlasHook } = await import("./index")
const { createToolExecuteAfterHandler } = await import("./tool-execute-after")
const { createToolExecuteBeforeHandler } = await import("./tool-execute-before")
const { MESSAGE_STORAGE } = await import("../../features/hook-message-injector")
const callerAgentBySession = new Map<string, string>()
type MockAtlasInput = Parameters<typeof createAtlasHook>[0] & {
_promptMock: ReturnType<typeof mock>
_sessionGetMock: ReturnType<typeof mock>
}
describe("atlas hook", () => {
let TEST_DIR: string
@@ -47,7 +29,7 @@ describe("atlas hook", () => {
function createMockPluginInput(overrides?: {
promptMock?: ReturnType<typeof mock>
sessionGetMock?: ReturnType<typeof mock>
}) {
}): MockAtlasInput {
const promptMock = overrides?.promptMock ?? mock(() => Promise.resolve())
const sessionGetMock = overrides?.sessionGetMock ?? mock(async ({ path }: { path: { id: string } }) => ({
data: {
@@ -55,40 +37,41 @@ describe("atlas hook", () => {
parentID: path.id.startsWith("ses_") ? "session-1" : "main-session-123",
},
}))
const client = createOpencodeClient({ baseUrl: "http://localhost" })
Reflect.set(client.session, "get", sessionGetMock)
Reflect.set(client.session, "prompt", promptMock)
Reflect.set(client.session, "promptAsync", promptMock)
return {
directory: TEST_DIR,
client: {
session: {
get: sessionGetMock,
prompt: promptMock,
promptAsync: promptMock,
},
},
project: {} as Parameters<typeof createAtlasHook>[0]["project"],
worktree: TEST_DIR,
serverUrl: new URL("http://localhost"),
$: {} as Parameters<typeof createAtlasHook>[0]["$"],
client,
_promptMock: promptMock,
_sessionGetMock: sessionGetMock,
} as Parameters<typeof createAtlasHook>[0] & {
_promptMock: ReturnType<typeof mock>
_sessionGetMock: ReturnType<typeof mock>
}
}
function setupMessageStorage(sessionID: string, agent: string): void {
const messageDir = join(MESSAGE_STORAGE, sessionID)
if (!existsSync(messageDir)) {
mkdirSync(messageDir, { recursive: true })
}
const messageData = {
agent,
model: { providerID: "anthropic", modelID: "claude-opus-4-7" },
}
writeFileSync(join(messageDir, "msg_test001.json"), JSON.stringify(messageData))
callerAgentBySession.set(sessionID, agent)
}
function cleanupMessageStorage(sessionID: string): void {
const messageDir = join(MESSAGE_STORAGE, sessionID)
if (existsSync(messageDir)) {
rmSync(messageDir, { recursive: true, force: true })
callerAgentBySession.delete(sessionID)
}
function createTestAtlasHook(
input = createMockPluginInput(),
options: Partial<AtlasHookOptions> = {},
): ReturnType<typeof createAtlasHook> {
const resolvedOptions: AtlasHookOptions = {
directory: TEST_DIR,
isCallerOrchestrator: async (sessionID) => callerAgentBySession.get(sessionID ?? "") === "atlas",
...options,
}
return createAtlasHook(input, resolvedOptions)
}
beforeEach(() => {
@@ -104,10 +87,12 @@ describe("atlas hook", () => {
mkdirSync(SISYPHUS_DIR, { recursive: true })
}
clearBoulderState(TEST_DIR)
callerAgentBySession.clear()
})
afterEach(() => {
_resetForTesting()
callerAgentBySession.clear()
clearBoulderState(TEST_DIR)
if (existsSync(TEST_DIR)) {
rmSync(TEST_DIR, { recursive: true, force: true })
@@ -117,7 +102,7 @@ describe("atlas hook", () => {
describe("tool.execute.after handler", () => {
test("should handle undefined output gracefully (issue #1035)", async () => {
// given - hook and undefined output (e.g., from /review command)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
// when - calling with undefined output
const result = await hook["tool.execute.after"](
@@ -131,7 +116,7 @@ describe("atlas hook", () => {
test("should ignore non-task tools", async () => {
// given - hook and non-task tool
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Test Tool",
output: "Original output",
@@ -164,7 +149,7 @@ describe("atlas hook", () => {
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -188,7 +173,7 @@ describe("atlas hook", () => {
const sessionID = "session-no-boulder-test"
setupMessageStorage(sessionID, "atlas")
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -225,7 +210,7 @@ describe("atlas hook", () => {
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -264,7 +249,7 @@ describe("atlas hook", () => {
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: `Task completed
@@ -301,7 +286,7 @@ session_id: ses_subagent_abc
const sessionID = "session-standalone-metadata-test"
setupMessageStorage(sessionID, "atlas")
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: `Task completed
@@ -349,7 +334,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Original output",
@@ -386,7 +371,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task output",
@@ -422,7 +407,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput({
const hook = createTestAtlasHook(createMockPluginInput({
sessionGetMock: mock(async () => {
throw new Error("session lookup failed")
}),
@@ -462,7 +447,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task output",
@@ -499,7 +484,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed",
@@ -536,7 +521,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed",
@@ -581,6 +566,7 @@ session_id: ses_standalone_def
ctx: createMockPluginInput(),
pendingFilePaths,
pendingTaskRefs,
isCallerOrchestrator: async (id) => callerAgentBySession.get(id ?? "") === "atlas",
})
const afterHandler = createToolExecuteAfterHandler({
ctx: createMockPluginInput(),
@@ -588,6 +574,7 @@ session_id: ses_standalone_def
pendingTaskRefs,
autoCommit: true,
getState: () => ({ promptFailureCount: 0 }),
isCallerOrchestrator: async (id) => callerAgentBySession.get(id ?? "") === "atlas",
})
// when - the task is captured before execution
@@ -634,7 +621,7 @@ session_id: ses_standalone_def
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: `Task completed successfully
@@ -684,7 +671,7 @@ session_id: ses_auth_flow_123
plan_name: "stable-task-key-plan",
})
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
// when - Atlas delegates task 1
await hook["tool.execute.before"](
@@ -744,7 +731,7 @@ session_id: ses_auth_flow_123
plan_name: "cross-task-resume-plan",
})
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
// when - Atlas resumes an explicit prior session
await hook["tool.execute.before"](
@@ -806,7 +793,7 @@ session_id: ses_old_task_111
},
})
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: `Task continued successfully
@@ -860,6 +847,7 @@ session_id: ses_old_task_111
ctx: createMockPluginInput(),
pendingFilePaths,
pendingTaskRefs,
isCallerOrchestrator: async (id) => callerAgentBySession.get(id ?? "") === "atlas",
})
const afterHandler = createToolExecuteAfterHandler({
ctx: createMockPluginInput(),
@@ -867,6 +855,7 @@ session_id: ses_old_task_111
pendingTaskRefs,
autoCommit: true,
getState: () => ({ promptFailureCount: 0 }),
isCallerOrchestrator: async (id) => callerAgentBySession.get(id ?? "") === "atlas",
})
// when - two task() calls start before either one completes
@@ -929,7 +918,7 @@ session_id: ses_parallel_collision_222
plan_name: "untrusted-session-id-plan",
})
const hook = createAtlasHook(createMockPluginInput({
const hook = createTestAtlasHook(createMockPluginInput({
sessionGetMock: mock(async ({ path }: { path: { id: string } }) => ({
data: {
id: path.id,
@@ -987,7 +976,7 @@ session_id: ses_untrusted_999
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -1022,7 +1011,7 @@ session_id: ses_untrusted_999
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -1061,7 +1050,7 @@ session_id: ses_untrusted_999
}
writeBoulderState(TEST_DIR, state)
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Sisyphus Task",
output: "Task completed successfully",
@@ -1093,7 +1082,7 @@ session_id: ses_untrusted_999
test("should append delegation reminder when orchestrator writes outside .sisyphus/", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Write",
output: "File written successfully",
@@ -1114,7 +1103,7 @@ session_id: ses_untrusted_999
test("should append delegation reminder when orchestrator edits outside .sisyphus/", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Edit",
output: "File edited successfully",
@@ -1133,7 +1122,7 @@ session_id: ses_untrusted_999
test("should NOT append reminder when orchestrator writes inside .sisyphus/", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1157,7 +1146,7 @@ session_id: ses_untrusted_999
const nonOrchestratorSession = "non-orchestrator-session"
setupMessageStorage(nonOrchestratorSession, "sisyphus-junior")
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1180,7 +1169,7 @@ session_id: ses_untrusted_999
test("should NOT append reminder for read-only tools", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File content"
const output = {
title: "Read",
@@ -1200,7 +1189,7 @@ session_id: ses_untrusted_999
test("should handle missing filePath gracefully", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1221,7 +1210,7 @@ session_id: ses_untrusted_999
describe("cross-platform path validation (Windows support)", () => {
test("should NOT append reminder when orchestrator writes inside .sisyphus\\ (Windows backslash)", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1242,7 +1231,7 @@ session_id: ses_untrusted_999
test("should NOT append reminder when orchestrator writes inside .sisyphus with mixed separators", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1263,7 +1252,7 @@ session_id: ses_untrusted_999
test("should NOT append reminder for absolute Windows path inside .sisyphus\\", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const originalOutput = "File written successfully"
const output = {
title: "Write",
@@ -1284,7 +1273,7 @@ session_id: ses_untrusted_999
test("should append reminder for Windows path outside .sisyphus\\", async () => {
// given
const hook = createAtlasHook(createMockPluginInput())
const hook = createTestAtlasHook(createMockPluginInput())
const output = {
title: "Write",
output: "File written successfully",
@@ -1339,7 +1328,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1360,7 +1349,7 @@ session_id: ses_untrusted_999
test("should not inject when no boulder state exists", async () => {
// given - no boulder state
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1388,7 +1377,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - main session fires idle but is NOT in boulder's session_ids
await hook.handler({
@@ -1419,7 +1408,7 @@ session_id: ses_untrusted_999
updateSessionAgent(subagentSessionID, "atlas")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - subagent session goes idle before explicit tracking appends it
await hook.handler({
@@ -1451,7 +1440,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
await hook.handler({
event: {
@@ -1480,7 +1469,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1513,7 +1502,7 @@ session_id: ses_untrusted_999
})
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
try {
// when
@@ -1545,7 +1534,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - send abort error then idle
await hook.handler({
@@ -1582,7 +1571,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - a recoverable runtime error fires without waiting for idle
await hook.handler({
@@ -1618,14 +1607,14 @@ session_id: ses_untrusted_999
const originalSetTimeout = globalThis.setTimeout
const scheduledDelays: number[] = []
globalThis.setTimeout = ((_handler: TimerHandler, timeout?: number, ..._args: unknown[]) => {
globalThis.setTimeout = ((_handler: Parameters<typeof setTimeout>[0], timeout?: number, ..._args: unknown[]) => {
scheduledDelays.push(timeout ?? 0)
return originalSetTimeout(() => undefined, 0)
}) as typeof setTimeout
try {
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - runtime error resumes immediately and OpenCode later emits stale idle
await hook.handler({
@@ -1671,7 +1660,7 @@ session_id: ses_untrusted_999
try {
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - runtime error resumes immediately and then the retry run emits assistant activity
await hook.handler({
@@ -1722,7 +1711,7 @@ session_id: ses_untrusted_999
}
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput, {
const hook = createTestAtlasHook(mockInput, {
directory: TEST_DIR,
backgroundManager: mockBackgroundManager,
})
@@ -1753,7 +1742,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput, {
const hook = createTestAtlasHook(mockInput, {
directory: TEST_DIR,
isContinuationStopped: (sessionID: string) => sessionID === MAIN_SESSION_ID,
})
@@ -1784,7 +1773,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - abort error, then message update, then idle
await hook.handler({
@@ -1827,7 +1816,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1869,7 +1858,7 @@ session_id: ses_untrusted_999
})
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1904,7 +1893,7 @@ session_id: ses_untrusted_999
setupMessageStorage(MAIN_SESSION_ID, "sisyphus")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1935,7 +1924,7 @@ session_id: ses_untrusted_999
setupMessageStorage(MAIN_SESSION_ID, "hephaestus")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
await hook.handler({
event: {
@@ -1965,7 +1954,7 @@ session_id: ses_untrusted_999
setupMessageStorage(MAIN_SESSION_ID, "sisyphus")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -1997,7 +1986,7 @@ session_id: ses_untrusted_999
registerAgentName("Atlas - Plan Executor")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -2028,7 +2017,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - fire multiple idle events in rapid succession (simulating infinite loop bug)
await hook.handler({
@@ -2069,7 +2058,7 @@ session_id: ses_untrusted_999
const promptMock = mock((): Promise<void> => Promise.reject(new Error("Bad Request")))
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2111,7 +2100,7 @@ session_id: ses_untrusted_999
promptMock.mockImplementationOnce(() => Promise.resolve())
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2147,7 +2136,7 @@ session_id: ses_untrusted_999
const promptMock = mock(() => Promise.reject(new Error("Bad Request")))
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2188,7 +2177,7 @@ session_id: ses_untrusted_999
const promptMock = mock(() => Promise.reject(new Error("Bad Request")))
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2233,7 +2222,7 @@ session_id: ses_untrusted_999
}
promptMock.mockImplementationOnce(() => Promise.resolve(undefined))
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2284,7 +2273,7 @@ session_id: ses_untrusted_999
const promptMock = mock(() => Promise.reject(new Error("Bad Request")))
const mockInput = createMockPluginInput({ promptMock })
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
const originalDateNow = Date.now
let now = 0
@@ -2328,7 +2317,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - create abort state then delete
await hook.handler({
@@ -2381,7 +2370,7 @@ session_id: ses_untrusted_999
updateSessionAgent(MAIN_SESSION_ID, "atlas")
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when
await hook.handler({
@@ -2407,7 +2396,7 @@ session_id: ses_untrusted_999
fakeNow = 10000
Date.now = () => fakeNow
globalThis.setTimeout = ((callback: TimerHandler, delay?: number, ...args: unknown[]) => {
globalThis.setTimeout = ((callback: Parameters<typeof setTimeout>[0], delay?: number, ...args: unknown[]) => {
const normalized = typeof delay === "number" ? delay : 0
if (normalized >= 5000) {
const timerID = originalSetTimeout(() => undefined, 0)
@@ -2463,7 +2452,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - first idle injects, second idle within cooldown schedules retry timer
await hook.handler({
@@ -2492,7 +2481,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - first idle injects, then 3 rapid idles within cooldown
await hook.handler({
@@ -2527,7 +2516,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
// when - first idle injects, second schedules retry, then plan completes before timer fires
await hook.handler({
@@ -2558,7 +2547,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
await hook.handler({
event: { type: "session.idle", properties: { sessionID: MAIN_SESSION_ID } },
@@ -2591,7 +2580,7 @@ session_id: ses_untrusted_999
writeBoulderState(TEST_DIR, state)
const mockInput = createMockPluginInput()
const hook = createAtlasHook(mockInput)
const hook = createTestAtlasHook(mockInput)
await hook.handler({
event: { type: "session.idle", properties: { sessionID: MAIN_SESSION_ID } },