feat(run): integrate session origins and agent detection into continuation state
- Update continuation-state to use session_origins from boulder state
- Add isTrackedDescendantSession helper for lineage detection
- Integrate getLastAgentFromSession for reliable agent detection
- Update completion tests for new lineage-aware continuation logic
- Add JSON backend tests for continuation state
🤖 Generated with assistance of OhMyOpenCode
This commit is contained in:
@@ -3,11 +3,13 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"
|
|||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
import type { RunContext } from "./types"
|
import type { RunContext } from "./types"
|
||||||
|
import { _resetForTesting, setSessionAgent } from "../../features/claude-code-session-state"
|
||||||
import { writeState as writeRalphLoopState } from "../../hooks/ralph-loop/storage"
|
import { writeState as writeRalphLoopState } from "../../hooks/ralph-loop/storage"
|
||||||
|
|
||||||
const testDirs: string[] = []
|
const testDirs: string[] = []
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
_resetForTesting()
|
||||||
while (testDirs.length > 0) {
|
while (testDirs.length > 0) {
|
||||||
const dir = testDirs.pop()
|
const dir = testDirs.pop()
|
||||||
if (dir) {
|
if (dir) {
|
||||||
@@ -458,6 +460,38 @@ describe("checkCompletionConditions continuation coverage", () => {
|
|||||||
expect(result).toBe(true)
|
expect(result).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("returns false when appended tracked descendant has no persisted messages but in-memory session agent matches atlas", async () => {
|
||||||
|
// given
|
||||||
|
spyOn(console, "log").mockImplementation(() => {})
|
||||||
|
const directory = createTempDir()
|
||||||
|
const planPath = join(directory, ".sisyphus", "plans", "session-agent-fallback-plan.md")
|
||||||
|
mkdirSync(join(directory, ".sisyphus", "plans"), { recursive: true })
|
||||||
|
writeFileSync(planPath, "- [ ] unfinished task\n", "utf-8")
|
||||||
|
writeBoulderStateFile(directory, planPath, ["ses_root_tracked", "ses_appended_child"], {
|
||||||
|
"ses_root_tracked": "direct",
|
||||||
|
"ses_appended_child": "appended",
|
||||||
|
})
|
||||||
|
|
||||||
|
const ctx = createMockContext(directory)
|
||||||
|
ctx.sessionID = "ses_appended_child"
|
||||||
|
setSessionAgent("ses_appended_child", "atlas")
|
||||||
|
ctx.client.session.get = mock(async ({ path }: { path: { id: string } }) => ({
|
||||||
|
data: {
|
||||||
|
id: path.id,
|
||||||
|
parentID: path.id === "ses_appended_child" ? "ses_root_tracked" : undefined,
|
||||||
|
},
|
||||||
|
})) as unknown as RunContext["client"]["session"]["get"]
|
||||||
|
ctx.client.session.messages = mock(async () => ({ data: [] })) as unknown as RunContext["client"]["session"]["messages"]
|
||||||
|
|
||||||
|
const { checkCompletionConditions } = await import("./completion")
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = await checkCompletionConditions(ctx)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
it("returns false when active ralph-loop continuation exists for this session", async () => {
|
it("returns false when active ralph-loop continuation exists for this session", async () => {
|
||||||
// given
|
// given
|
||||||
spyOn(console, "log").mockImplementation(() => {})
|
spyOn(console, "log").mockImplementation(() => {})
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getPlanProgress, readBoulderState } from "../../features/boulder-state"
|
import { getPlanProgress, readBoulderState } from "../../features/boulder-state"
|
||||||
|
import { getSessionAgent } from "../../features/claude-code-session-state"
|
||||||
import {
|
import {
|
||||||
getActiveContinuationMarkerReason,
|
getActiveContinuationMarkerReason,
|
||||||
isContinuationMarkerActive,
|
isContinuationMarkerActive,
|
||||||
@@ -65,6 +66,7 @@ async function hasActiveBoulderContinuation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sessionAgent = await getLastAgentFromSession(sessionID, client)
|
const sessionAgent = await getLastAgentFromSession(sessionID, client)
|
||||||
|
?? getSessionAgent(sessionID)
|
||||||
if (!sessionAgent) {
|
if (!sessionAgent) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user