chore: rebuild CentOS7 release package
This commit is contained in:
@@ -313,16 +313,22 @@ function createFakeClaudeHistory(homeDir) {
|
||||
return { sessionId, projectDir: 'tmp-project', filePath };
|
||||
}
|
||||
|
||||
function createFakeCodexHistory(homeDir) {
|
||||
function createFakeCodexHistory(homeDir, options = {}) {
|
||||
const sessionsDir = path.join(homeDir, '.codex', 'sessions', '2026', '03', '12');
|
||||
mkdirp(sessionsDir);
|
||||
const threadId = 'codex-import-thread';
|
||||
const rolloutPath = path.join(sessionsDir, 'rollout-2026-03-12T00-00-00-codex-import-thread.jsonl');
|
||||
const threadId = options.threadId || 'codex-import-thread';
|
||||
const cwd = options.cwd || '/tmp/project-b';
|
||||
const userText = options.userText || 'Codex import prompt';
|
||||
const answerText = options.answerText || 'Codex import answer';
|
||||
const source = options.source || 'exec';
|
||||
const cliVersion = options.cliVersion || '0.114.0';
|
||||
const fileStamp = options.fileStamp || '2026-03-12T00-00-00';
|
||||
const rolloutPath = path.join(sessionsDir, `rollout-${fileStamp}-${threadId}.jsonl`);
|
||||
const rolloutLines = [
|
||||
JSON.stringify({
|
||||
timestamp: '2026-03-12T00:00:00.000Z',
|
||||
type: 'session_meta',
|
||||
payload: { id: threadId, cwd: '/tmp/project-b', cli_version: '0.114.0', source: 'exec' },
|
||||
payload: { id: threadId, cwd, cli_version: cliVersion, source },
|
||||
}),
|
||||
JSON.stringify({
|
||||
timestamp: '2026-03-12T00:00:00.100Z',
|
||||
@@ -336,7 +342,7 @@ function createFakeCodexHistory(homeDir) {
|
||||
JSON.stringify({
|
||||
timestamp: '2026-03-12T00:00:01.000Z',
|
||||
type: 'event_msg',
|
||||
payload: { type: 'user_message', message: 'Codex import prompt' },
|
||||
payload: { type: 'user_message', message: userText },
|
||||
}),
|
||||
JSON.stringify({
|
||||
timestamp: '2026-03-12T00:00:02.000Z',
|
||||
@@ -344,7 +350,7 @@ function createFakeCodexHistory(homeDir) {
|
||||
payload: {
|
||||
type: 'message',
|
||||
role: 'assistant',
|
||||
content: [{ type: 'output_text', text: 'Codex import answer' }],
|
||||
content: [{ type: 'output_text', text: answerText }],
|
||||
},
|
||||
}),
|
||||
JSON.stringify({
|
||||
@@ -419,7 +425,7 @@ function createFakeCodexHistory(homeDir) {
|
||||
estimated_bytes INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
INSERT INTO threads (id, rollout_path, created_at, updated_at, source, model_provider, cwd, title, sandbox_policy, approval_mode, cli_version)
|
||||
VALUES ('${threadId}', '${rolloutPath.replace(/'/g, "''")}', 1, 2, 'exec', 'OpenAI', '/tmp/project-b', 'Codex import prompt', '{}', 'never', '0.114.0');
|
||||
VALUES ('${threadId}', '${rolloutPath.replace(/'/g, "''")}', 1, 2, '${source}', 'OpenAI', '${cwd.replace(/'/g, "''")}', '${userText.replace(/'/g, "''")}', '{}', 'never', '${cliVersion}');
|
||||
INSERT INTO logs (ts, ts_nanos, level, target, thread_id) VALUES (1, 0, 'INFO', 'test', '${threadId}');
|
||||
`);
|
||||
|
||||
@@ -500,6 +506,15 @@ function assertFrontendGenerationControlsContract() {
|
||||
!source.includes(staleDefaultApprovalWarning),
|
||||
'Frontend should not show the stale default-mode approval warning after Codex App approvals are supported'
|
||||
);
|
||||
assert(
|
||||
!source.includes('Codex App 暂不支持导入') && !source.includes('Codex App 模式暂不支持导入'),
|
||||
'Frontend should not disable Codex App native session import'
|
||||
);
|
||||
assert(
|
||||
source.includes("send({ type: 'list_codex_sessions', agent: importAgent })") &&
|
||||
source.includes("send({ type: 'import_codex_session', agent: importAgent"),
|
||||
'Frontend Codex import modal should pass the selected Codex-like agent'
|
||||
);
|
||||
}
|
||||
|
||||
function assertFrontendComposerMcpContract() {
|
||||
@@ -674,6 +689,14 @@ async function main() {
|
||||
createFakeClaudeHistory(homeDir);
|
||||
createFakeCodexConfig(homeDir);
|
||||
const codexFixture = createFakeCodexHistory(homeDir);
|
||||
const codexAppImportFixture = createFakeCodexHistory(homeDir, {
|
||||
threadId: 'codexapp-import-thread',
|
||||
cwd: '/tmp/project-c',
|
||||
userText: 'Codex App import prompt',
|
||||
answerText: 'Codex App import answer',
|
||||
source: 'vscode',
|
||||
fileStamp: '2026-03-12T00-00-10',
|
||||
});
|
||||
|
||||
const port = await getFreePort();
|
||||
const password = 'Regression!234';
|
||||
@@ -1870,6 +1893,48 @@ async function main() {
|
||||
assert(importedCodex.messages?.[0]?.content === 'Codex import prompt', 'Codex import kept wrapper instructions');
|
||||
assert(importedCodex.totalUsage?.inputTokens === 20, 'Codex import usage parse failed');
|
||||
|
||||
ws.send(JSON.stringify({ type: 'list_codex_sessions', agent: 'codexapp' }));
|
||||
const codexAppImportSessions = await nextMessage(messages, ws, (msg) => msg.type === 'codex_sessions');
|
||||
const codexAppImportItem = codexAppImportSessions.sessions.find((item) => item.threadId === codexAppImportFixture.threadId);
|
||||
assert(codexAppImportItem, 'Codex App session listing failed');
|
||||
assert(codexAppImportItem.agent === 'codexapp', 'Codex App import listing should echo target agent');
|
||||
assert(codexAppImportItem.alreadyImported === false, 'Codex App import should not reuse old Codex imported state');
|
||||
|
||||
ws.send(JSON.stringify({
|
||||
type: 'import_codex_session',
|
||||
agent: 'codexapp',
|
||||
threadId: codexAppImportItem.threadId,
|
||||
rolloutPath: codexAppImportItem.rolloutPath,
|
||||
}));
|
||||
const importedCodexApp = await nextMessage(messages, ws, (msg) => msg.type === 'session_info' && msg.agent === 'codexapp' && msg.title === 'Codex App import prompt');
|
||||
assert(importedCodexApp.messages?.[0]?.content === 'Codex App import prompt', 'Codex App import parsed wrong first message');
|
||||
assert(importedCodexApp.totalUsage?.inputTokens === 20, 'Codex App import usage parse failed');
|
||||
const importedCodexAppPath = path.join(sessionsDir, `${importedCodexApp.sessionId}.json`);
|
||||
const storedImportedCodexApp = JSON.parse(fs.readFileSync(importedCodexAppPath, 'utf8'));
|
||||
assert(storedImportedCodexApp.agent === 'codexapp', 'Codex App import should persist codexapp agent');
|
||||
assert(storedImportedCodexApp.codexAppThreadId === codexAppImportFixture.threadId, 'Codex App import should persist codexAppThreadId');
|
||||
assert(!storedImportedCodexApp.codexThreadId, 'Codex App import should not persist legacy codexThreadId');
|
||||
|
||||
ws.send(JSON.stringify({ type: 'list_codex_sessions', agent: 'codexapp' }));
|
||||
const codexAppImportSessionsAfter = await nextMessage(messages, ws, (msg) => msg.type === 'codex_sessions');
|
||||
const codexAppImportItemAfter = codexAppImportSessionsAfter.sessions.find((item) => item.threadId === codexAppImportFixture.threadId);
|
||||
assert(codexAppImportItemAfter?.alreadyImported === true, 'Codex App import listing should mark codexAppThreadId as imported');
|
||||
|
||||
ws.send(JSON.stringify({ type: 'delete_session', sessionId: importedCodexApp.sessionId }));
|
||||
await nextMessage(messages, ws, (msg) => msg.type === 'session_list' && !msg.sessions.some((s) => s.id === importedCodexApp.sessionId));
|
||||
assert(!fs.existsSync(importedCodexAppPath), 'Deleting Codex App imported session did not remove cc-web session JSON');
|
||||
assert(fs.existsSync(codexAppImportFixture.rolloutPath), 'Deleting Codex App imported session should keep rollout history for recovery');
|
||||
|
||||
ws.send(JSON.stringify({
|
||||
type: 'import_codex_session',
|
||||
agent: 'codexapp',
|
||||
threadId: codexAppImportFixture.threadId,
|
||||
rolloutPath: codexAppImportFixture.rolloutPath,
|
||||
}));
|
||||
const restoredCodexApp = await nextMessage(messages, ws, (msg) => msg.type === 'session_info' && msg.agent === 'codexapp' && msg.title === 'Codex App import prompt');
|
||||
assert(restoredCodexApp.sessionId !== importedCodexApp.sessionId, 'Codex App deleted session should be recreated from rollout history');
|
||||
assert(restoredCodexApp.messages?.[0]?.content === 'Codex App import prompt', 'Codex App re-import should restore messages after cc-web deletion');
|
||||
|
||||
const importedSessionId = importedCodex.sessionId;
|
||||
ws.send(JSON.stringify({ type: 'delete_session', sessionId: importedSessionId }));
|
||||
await nextMessage(messages, ws, (msg) => msg.type === 'session_list' && !msg.sessions.some((s) => s.id === importedSessionId));
|
||||
|
||||
Reference in New Issue
Block a user