Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ const CURSOR_RESUME_SESSION_RE = /(?:^|\s)(?:--resume|resume)(?:=|\s+)([A-Za-z0-
const OPENCODE_SESSION_RE = /(?:^|\s)--session(?:=|\s+)([A-Za-z0-9_-]{8,128})(?=\s|$)/;
// Oh My Pi and omo are both pi-derived and accept the identical `--resume|-r` form.
const PI_RESUME_SESSION_RE = /(?:^|\s)(?:--resume|-r)(?:=|\s+)([A-Za-z0-9_-]{8,128})(?=\s|$)/;
// omo's canonical continuation flag is `--session-id <id>` (its `--resume` takes
// no value and opens a picker, so no id ever appears in argv for that form).
// ChatMux itself resumes omo with `--session-id` in `server/pi-cli.ts`, so a
// pane started that way must link back to its transcript session.
const OMO_SESSION_ID_RE = /(?:^|\s)--session-id(?:=|\s+)([A-Za-z0-9_-]{8,128})(?=\s|$)/;
const TRANSCRIPT_FILE_SESSION_ID_RE = /_([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
const CODEX_ROLLOUT_FILE_RE = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
const MAX_RUNTIME_DESCRIPTORS = 2_048;
Expand Down Expand Up @@ -202,7 +207,12 @@ export function extractExternalResumeSessionId(
if (kind === 'codex') return extractCodexResumeThreadId(processArgs);
if (kind === 'cursor') return processArgs.match(CURSOR_RESUME_SESSION_RE)?.[1] ?? null;
if (kind === 'opencode') return processArgs.match(OPENCODE_SESSION_RE)?.[1] ?? null;
if (kind === 'omp' || kind === 'omo') return processArgs.match(PI_RESUME_SESSION_RE)?.[1] ?? null;
if (kind === 'omp') return processArgs.match(PI_RESUME_SESSION_RE)?.[1] ?? null;
if (kind === 'omo') {
return processArgs.match(OMO_SESSION_ID_RE)?.[1]
?? processArgs.match(PI_RESUME_SESSION_RE)?.[1]
?? null;
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,27 @@ test('extractExternalResumeSessionId recognizes every supported native resume fo
assert.equal(extractExternalResumeSessionId('cursor', 'agent --version'), null);
});

// omo continues a session with `--session-id <id>` — the flag ChatMux itself
// uses in `server/pi-cli.ts`. Its `--resume` takes no value (interactive
// picker), so a pane resumed with `--session-id` must still link back to its
// transcript session.
test('extractExternalResumeSessionId links omo panes started with --session-id', () => {
assert.equal(
extractExternalResumeSessionId('omo', 'omo --session-id 019ff9fa-abab-78a3-83b0-67c261374f42'),
'019ff9fa-abab-78a3-83b0-67c261374f42',
);
assert.equal(
extractExternalResumeSessionId('omo', 'node /home/user/bin/omo --session-id=019ff9fa-abab-78a3-83b0-67c261374f42'),
'019ff9fa-abab-78a3-83b0-67c261374f42',
);
// pi-derived `--resume <id>` argv still links if a wrapper passes it through.
assert.equal(extractExternalResumeSessionId('omo', 'omo --resume 019f848f_ff71_77f0'), '019f848f_ff71_77f0');
// The valueless picker form carries no id and must not match the prompt text.
assert.equal(extractExternalResumeSessionId('omo', 'omo --resume'), null);
// `--session-id` must never leak into the omp branch, which has no such flag.
assert.equal(extractExternalResumeSessionId('omp', 'omp --session-id 019f848f_ff71_77f0'), null);
});


test('parseClaudeRuntimeSession accepts the PID-bound native Claude receipt', () => {
const sessionId = '92869134-b4df-453e-b3a6-ed1d750d69d9';
Expand Down