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 { tmpdir } from "node:os"
|
||||
import type { RunContext } from "./types"
|
||||
import { _resetForTesting, setSessionAgent } from "../../features/claude-code-session-state"
|
||||
import { writeState as writeRalphLoopState } from "../../hooks/ralph-loop/storage"
|
||||
|
||||
const testDirs: string[] = []
|
||||
|
||||
afterEach(() => {
|
||||
_resetForTesting()
|
||||
while (testDirs.length > 0) {
|
||||
const dir = testDirs.pop()
|
||||
if (dir) {
|
||||
@@ -458,6 +460,38 @@ describe("checkCompletionConditions continuation coverage", () => {
|
||||
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 () => {
|
||||
// given
|
||||
spyOn(console, "log").mockImplementation(() => {})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getPlanProgress, readBoulderState } from "../../features/boulder-state"
|
||||
import { getSessionAgent } from "../../features/claude-code-session-state"
|
||||
import {
|
||||
getActiveContinuationMarkerReason,
|
||||
isContinuationMarkerActive,
|
||||
@@ -65,6 +66,7 @@ async function hasActiveBoulderContinuation(
|
||||
}
|
||||
|
||||
const sessionAgent = await getLastAgentFromSession(sessionID, client)
|
||||
?? getSessionAgent(sessionID)
|
||||
if (!sessionAgent) {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user