mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 06:59:42 +02:00
Merge pull request #386 from irisitymichaelgrundberg/feat/codex-resume
Merging with the phone-overview resumeId fix and the two unified-list doc passages applied on master.
This commit is contained in:
@@ -148,6 +148,7 @@ import {
|
||||
import { LRUMap } from '../../utils/lru-map.js';
|
||||
import { findLatestOmpSessionId } from '../../utils/omp-session-resolver.js';
|
||||
import { scanOmpSessionsHistory } from '../../omp-transcript.js';
|
||||
import { scanCodexSessionsHistory, codexThreadBySessionId } from '../../codex-transcript.js';
|
||||
import {
|
||||
getLastTranscriptResponse,
|
||||
isExternalCliTranscriptMode,
|
||||
@@ -4164,6 +4165,13 @@ export function registerSessionRoutes(
|
||||
// Persisted sessions (state.json). resumeSessionId is the Claude
|
||||
// conversation UUID a resumed session continues — feed it to the merge's
|
||||
// alias map so its transcript row folds into this session.
|
||||
//
|
||||
// codex keeps its thread id in `codexConfig` instead, and state.json stores
|
||||
// that, so read it here as well. Without it a resumed codex session that has
|
||||
// been demoted to a persisted-only record loses its alias and duplicates: the
|
||||
// originator fallback below cannot rescue that one, because a RESUMED rollout
|
||||
// keeps the original session_meta (see findActiveCodexFile) and so still
|
||||
// names whichever pane first created the thread.
|
||||
const persisted: PersistedSessionInput[] = Object.values(ctx.store.getState().sessions).map((p) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
@@ -4172,7 +4180,7 @@ export function registerSessionRoutes(
|
||||
workingDir: p.workingDir,
|
||||
createdAt: p.createdAt,
|
||||
lastActivityAt: p.lastActivityAt,
|
||||
claudeSessionId: p.resumeSessionId,
|
||||
claudeSessionId: p.resumeSessionId || p.codexConfig?.resumeSessionId,
|
||||
pinned: p.pinned,
|
||||
pinnedAt: p.pinnedAt,
|
||||
}));
|
||||
@@ -4240,6 +4248,49 @@ export function registerSessionRoutes(
|
||||
// Best-effort, same as the claude scan above.
|
||||
}
|
||||
|
||||
// Codex's own rollout store (~/.codex/sessions) — the same treatment omp
|
||||
// gets above, and for the same reason: codex writes no Claude transcript, so
|
||||
// without this a codex conversation disappears from the list as soon as its
|
||||
// session record does. `resumeId` is the rollout's own thread id, which is
|
||||
// what `codex resume` takes; see codex-transcript.ts.
|
||||
try {
|
||||
const codexRows = await scanCodexSessionsHistory();
|
||||
for (const h of codexRows) {
|
||||
history.push({
|
||||
sessionId: h.sessionId,
|
||||
workingDir: h.workingDir,
|
||||
sizeBytes: h.sizeBytes,
|
||||
lastModified: h.lastModified,
|
||||
firstPrompt: h.firstPrompt,
|
||||
lastPrompt: h.lastPrompt,
|
||||
mode: 'codex',
|
||||
resumeId: h.sessionId,
|
||||
});
|
||||
}
|
||||
|
||||
// Fold a FRESH codex pane into its own rollout row. A resumed one already
|
||||
// folds, because Session sets `claudeSessionId` from the resume id it was
|
||||
// given; a fresh one has no thread id until codex writes the rollout, so
|
||||
// the link has to come from the other side. Codeman spawns every codex pane
|
||||
// with CODEX_INTERNAL_ORIGINATOR_OVERRIDE=codeman_<sessionId>, and codex
|
||||
// stamps that into session_meta.originator, so the rollout names the pane.
|
||||
//
|
||||
// Newest rollout wins: `/new` typed inside the TUI leaves several rollouts
|
||||
// carrying the same originator, and the pane is on the most recent one.
|
||||
// Rows arrive newest-first, so the first match is it.
|
||||
//
|
||||
// Never overwrites an id a session already knows — that one came from the
|
||||
// resume path and is authoritative.
|
||||
const codexThreads = codexThreadBySessionId(codexRows);
|
||||
for (const row of [...live, ...persisted]) {
|
||||
if (row.claudeSessionId && row.claudeSessionId !== row.id) continue;
|
||||
const threadId = codexThreads.get(row.id);
|
||||
if (threadId) row.claudeSessionId = threadId;
|
||||
}
|
||||
} catch {
|
||||
// Best-effort, same as the two scans above.
|
||||
}
|
||||
|
||||
// Mux process stats (best-effort; guard against mocks lacking the method).
|
||||
let mux: MuxStatInput[] = [];
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user