Skip to content

Commit a295202

Browse files
fix(ralph-loop): generate transcript path from sessionID instead of relying on event properties (#355)
OpenCode doesn't pass transcriptPath in the session.idle event properties, which caused detectCompletionPromise to always return false (the first check returns early if transcriptPath is undefined). This fix: - Imports getTranscriptPath from claude-code-hooks/transcript - Generates the transcript path from sessionID instead of reading from event - Adds optional getTranscriptPath callback to RalphLoopOptions for testability Fixes #354 Co-authored-by: sisyphus-dev-ai <[email protected]>
1 parent e3040ec commit a295202

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

src/hooks/ralph-loop/index.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,17 +329,19 @@ describe("ralph-loop", () => {
329329

330330
test("should detect completion promise and stop loop", async () => {
331331
// #given - active loop with transcript containing completion
332-
const hook = createRalphLoopHook(createMockPluginInput())
332+
const transcriptPath = join(TEST_DIR, "transcript.jsonl")
333+
const hook = createRalphLoopHook(createMockPluginInput(), {
334+
getTranscriptPath: () => transcriptPath,
335+
})
333336
hook.startLoop("session-123", "Build something", { completionPromise: "COMPLETE" })
334337

335-
const transcriptPath = join(TEST_DIR, "transcript.jsonl")
336338
writeFileSync(transcriptPath, JSON.stringify({ content: "Task done <promise>COMPLETE</promise>" }))
337339

338-
// #when - session goes idle with transcript
340+
// #when - session goes idle (transcriptPath now derived from sessionID via getTranscriptPath)
339341
await hook.event({
340342
event: {
341343
type: "session.idle",
342-
properties: { sessionID: "session-123", transcriptPath },
344+
properties: { sessionID: "session-123" },
343345
},
344346
})
345347

src/hooks/ralph-loop/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
DEFAULT_COMPLETION_PROMISE,
99
} from "./constants"
1010
import type { RalphLoopState, RalphLoopOptions } from "./types"
11+
import { getTranscriptPath as getDefaultTranscriptPath } from "../claude-code-hooks/transcript"
1112

1213
export * from "./types"
1314
export * from "./constants"
@@ -48,6 +49,7 @@ export function createRalphLoopHook(
4849
const sessions = new Map<string, SessionState>()
4950
const config = options?.config
5051
const stateDir = config?.state_dir
52+
const getTranscriptPath = options?.getTranscriptPath ?? getDefaultTranscriptPath
5153

5254
function getSessionState(sessionID: string): SessionState {
5355
let state = sessions.get(sessionID)
@@ -149,7 +151,8 @@ export function createRalphLoopHook(
149151
return
150152
}
151153

152-
const transcriptPath = props?.transcriptPath as string | undefined
154+
// Generate transcript path from sessionID - OpenCode doesn't pass it in event properties
155+
const transcriptPath = getTranscriptPath(sessionID)
153156

154157
if (detectCompletionPromise(transcriptPath, state.completion_promise)) {
155158
log(`[${HOOK_NAME}] Completion detected!`, {

src/hooks/ralph-loop/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export interface RalphLoopState {
1212

1313
export interface RalphLoopOptions {
1414
config?: RalphLoopConfig
15+
getTranscriptPath?: (sessionId: string) => string
1516
}

0 commit comments

Comments
 (0)