Wires the host's mirror hook end-to-end: FindCodexSessionFile walks ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*-<thread_id>.jsonl to prove the path for the captured thread_id, then logs the no-op. Real rewrite is deferred to v2: codex keys tool calls by `call_<id>` not the `toolu_<id>` Plexum's canonical block format uses, so a v1 rewriter would never find a matching id. When tool-call id round-trip through codex's native surface lands, the rewriter plugs into this file's path resolver. Also rescues cmd/plexum-openai-provider-plugin/main.go from .gitignore (the bare 'plexum-openai-provider-plugin' pattern was too greedy — it matched the source directory). Tightened to '/plexum-openai-provider-plugin' + '/bin/' so only built binaries get ignored.
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
// 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_<id>`, not the `toolu_<id>` 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/<YYYY>/<MM>/<DD>/rollout-<ISO>-<thread_id>.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
|
|
}
|