// session_mutate.go — codex session file path resolution. The actual // JSONL rewrite is deferred (see main.go MutateSession comment): codex // keys tool calls by `call_`, not the `toolu_` Plexum uses, // so a v1 mirror would never match anything. We expose the path // finder here so the host-side wiring telemetry stays useful and the // v2 rewriter has its entry point. // // Codex layout (observed): // // ~/.codex/sessions///
/rollout--.jsonl // // Older layout (pre-0.5x) wrote into the top-level sessions dir with // the same filename convention. We probe both. package runner import ( "errors" "fmt" "os" "path/filepath" "strings" ) // FindCodexSessionFile resolves the rollout JSONL for the thread_id // captured into workspace/.plexum-codex-session. Returns ("", error) // when no session id is recorded yet OR no matching file is on disk. func FindCodexSessionFile(workspace string) (string, error) { threadID := loadSessionID(workspace) if threadID == "" { return "", errors.New("no thread_id captured yet") } home, err := os.UserHomeDir() if err != nil { return "", err } root := filepath.Join(home, ".codex", "sessions") var found string err = filepath.WalkDir(root, func(p string, d os.DirEntry, err error) error { if err != nil { return nil // tolerate per-entry errors; keep walking } if d.IsDir() { return nil } name := d.Name() if !strings.HasSuffix(name, ".jsonl") && !strings.HasSuffix(name, ".json") { return nil } if strings.Contains(name, threadID) { found = p return filepath.SkipAll } return nil }) if err != nil { return "", err } if found == "" { return "", fmt.Errorf("no rollout file for thread_id=%s under %s", threadID, root) } return found, nil }