chore: rebuild CentOS7 release package

This commit is contained in:
shiyue
2026-07-01 00:00:29 +08:00
parent 8e4b20f15d
commit ddd97398e7
10 changed files with 251 additions and 37 deletions

View File

@@ -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));