feat(codex): import and resume sessions from runners (#1088)

* fix codex import resume flow

* fix hub restart session active state

* fix codex transcript workspace scoping

* Address Codex import review findings

* Fix Codex import machine selection

* Update Codex sessions error test

* Address Codex import review findings

* Preserve forked Codex session id on sync

* Make Codex duplicate cleanup source-aware

* Handle Codex archive failures

* Limit existing session flag to Codex

* Preserve Codex import machine binding

* fix: rebase runner Codex import onto current main

* fix: preserve runner-scoped Codex import behavior

---------

Co-authored-by: syy <815728149@qq.com>
This commit is contained in:
NightWatcher314
2026-07-19 14:14:42 +08:00
committed by GitHub
co-authored by syy
parent 651c83a1d9
commit 64834467e3
42 changed files with 2536 additions and 133 deletions
+52
View File
@@ -126,6 +126,58 @@ export const CursorChatStoreStatusSchema = z.object({
export type CursorChatStoreStatus = z.infer<typeof CursorChatStoreStatusSchema>
export const CodexImportedMessageSchema = z.union([
z.object({
role: z.literal('user'),
content: z.object({ type: z.literal('text'), text: z.string() }),
meta: z.object({ sentFrom: z.literal('cli') })
}),
z.object({
role: z.literal('agent'),
content: z.object({ type: z.literal('codex'), data: z.unknown() }),
meta: z.object({ sentFrom: z.literal('cli') })
})
])
export const CodexLocalSessionSummarySchema = z.object({
id: z.string().min(1),
title: z.string(),
lastUserMessage: z.string().nullable().optional(),
cwd: z.string().nullable().optional(),
file: z.string().min(1),
modifiedAt: z.number(),
originator: z.string().nullable().optional(),
cliVersion: z.string().nullable().optional(),
source: z.string().nullable().optional(),
threadSource: z.string().nullable().optional(),
forkedFromId: z.string().nullable().optional()
})
export const CodexLocalSessionWithMessagesSchema = CodexLocalSessionSummarySchema.extend({
messages: z.array(CodexImportedMessageSchema)
})
export const ListCodexSessionsRpcRequestSchema = z.object({
cwd: z.string().nullable().optional(),
sessionIds: z.array(z.string().min(1)).optional()
})
export const ListCodexSessionsRpcResponseSchema = z.union([
z.object({ success: z.literal(true), sessions: z.array(z.union([CodexLocalSessionSummarySchema, CodexLocalSessionWithMessagesSchema])) }),
z.object({ success: z.literal(false), error: z.string() })
])
export const ArchiveCodexSessionRpcRequestSchema = z.object({ sessionId: z.string().min(1) })
export const ArchiveCodexSessionRpcResponseSchema = z.union([
z.object({ success: z.literal(true), archivedPath: z.string() }),
z.object({ success: z.literal(false), error: z.string() })
])
export type ListCodexSessionsRpcRequest = z.infer<typeof ListCodexSessionsRpcRequestSchema>
export type ListCodexSessionsRpcResponse = z.infer<typeof ListCodexSessionsRpcResponseSchema>
export type ArchiveCodexSessionRpcRequest = z.infer<typeof ArchiveCodexSessionRpcRequestSchema>
export type ArchiveCodexSessionRpcResponse = z.infer<typeof ArchiveCodexSessionRpcResponseSchema>
export const SessionCollaborationModeRequestSchema = z.object({
mode: CodexCollaborationModeSchema
})