chore: rebuild CentOS7 release package
This commit is contained in:
Binary file not shown.
@@ -66,7 +66,8 @@
|
|||||||
codexapp: 'Codex App',
|
codexapp: 'Codex App',
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_AGENT = 'claude';
|
const PRIMARY_UI_AGENT = 'codexapp';
|
||||||
|
const DEFAULT_AGENT = PRIMARY_UI_AGENT;
|
||||||
const SESSION_CACHE_LIMIT = 4;
|
const SESSION_CACHE_LIMIT = 4;
|
||||||
const SESSION_CACHE_MAX_WEIGHT = 1_500_000;
|
const SESSION_CACHE_MAX_WEIGHT = 1_500_000;
|
||||||
const SIDEBAR_SWIPE_TRIGGER = 72;
|
const SIDEBAR_SWIPE_TRIGGER = 72;
|
||||||
@@ -178,8 +179,8 @@
|
|||||||
let hasGrouped = false; // 本次输出是否已触发过折叠
|
let hasGrouped = false; // 本次输出是否已触发过折叠
|
||||||
let cmdMenuIndex = -1;
|
let cmdMenuIndex = -1;
|
||||||
let currentMode = 'yolo';
|
let currentMode = 'yolo';
|
||||||
let currentModel = 'opus';
|
let currentModel = '';
|
||||||
let currentAgent = AGENT_LABELS[localStorage.getItem('cc-web-agent')] ? localStorage.getItem('cc-web-agent') : DEFAULT_AGENT;
|
let currentAgent = DEFAULT_AGENT;
|
||||||
let currentTheme = (document.documentElement.dataset.theme || localStorage.getItem('cc-web-theme') || 'washi');
|
let currentTheme = (document.documentElement.dataset.theme || localStorage.getItem('cc-web-theme') || 'washi');
|
||||||
let showAgentDividerTime = localStorage.getItem(DIVIDER_TIME_STORAGE_KEY) !== '0';
|
let showAgentDividerTime = localStorage.getItem(DIVIDER_TIME_STORAGE_KEY) !== '0';
|
||||||
let codexConfigCache = null;
|
let codexConfigCache = null;
|
||||||
@@ -268,6 +269,7 @@
|
|||||||
const chatSessionIdBtn = $('#chat-session-id-btn');
|
const chatSessionIdBtn = $('#chat-session-id-btn');
|
||||||
const chatAgentBtn = $('#chat-agent-btn');
|
const chatAgentBtn = $('#chat-agent-btn');
|
||||||
const chatAgentMenu = $('#chat-agent-menu');
|
const chatAgentMenu = $('#chat-agent-menu');
|
||||||
|
const chatAgentPicker = chatAgentBtn?.closest('.chat-agent-picker') || chatAgentMenu?.closest('.chat-agent-picker') || null;
|
||||||
const chatRuntimeState = $('#chat-runtime-state');
|
const chatRuntimeState = $('#chat-runtime-state');
|
||||||
const chatCwd = $('#chat-cwd');
|
const chatCwd = $('#chat-cwd');
|
||||||
const userOutlineBtn = $('#user-outline-btn');
|
const userOutlineBtn = $('#user-outline-btn');
|
||||||
@@ -308,6 +310,14 @@
|
|||||||
return AGENT_LABELS[agent] ? agent : DEFAULT_AGENT;
|
return AGENT_LABELS[agent] ? agent : DEFAULT_AGENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeUiAgent() {
|
||||||
|
return PRIMARY_UI_AGENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPrimaryUiAgent(agent) {
|
||||||
|
return normalizeAgent(agent) === PRIMARY_UI_AGENT;
|
||||||
|
}
|
||||||
|
|
||||||
function isCodexLikeAgent(agent) {
|
function isCodexLikeAgent(agent) {
|
||||||
const normalized = normalizeAgent(agent);
|
const normalized = normalizeAgent(agent);
|
||||||
return normalized === 'codex' || normalized === 'codexapp';
|
return normalized === 'codex' || normalized === 'codexapp';
|
||||||
@@ -3750,7 +3760,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getVisibleSessions() {
|
function getVisibleSessions() {
|
||||||
return sessions.filter((s) => normalizeAgent(s.agent) === currentAgent);
|
return sessions.filter((s) => isPrimaryUiAgent(s.agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeSessionSearchQuery(query) {
|
function normalizeSessionSearchQuery(query) {
|
||||||
@@ -4123,9 +4133,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateAgentScopedUI() {
|
function updateAgentScopedUI() {
|
||||||
|
if (chatAgentPicker) chatAgentPicker.hidden = true;
|
||||||
|
if (chatAgentMenu) chatAgentMenu.hidden = true;
|
||||||
if (chatAgentBtn) {
|
if (chatAgentBtn) {
|
||||||
chatAgentBtn.textContent = AGENT_LABELS[currentAgent];
|
chatAgentBtn.textContent = AGENT_LABELS[currentAgent];
|
||||||
chatAgentBtn.setAttribute('aria-expanded', chatAgentMenu && !chatAgentMenu.hidden ? 'true' : 'false');
|
chatAgentBtn.setAttribute('aria-expanded', 'false');
|
||||||
}
|
}
|
||||||
if (chatAgentMenu) {
|
if (chatAgentMenu) {
|
||||||
chatAgentMenu.querySelectorAll('.chat-agent-option').forEach((btn) => {
|
chatAgentMenu.querySelectorAll('.chat-agent-option').forEach((btn) => {
|
||||||
@@ -4144,7 +4156,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCurrentAgent(agent) {
|
function setCurrentAgent(agent) {
|
||||||
currentAgent = normalizeAgent(agent);
|
currentAgent = normalizeUiAgent(agent);
|
||||||
localStorage.setItem('cc-web-agent', currentAgent);
|
localStorage.setItem('cc-web-agent', currentAgent);
|
||||||
currentMode = localStorage.getItem(getAgentModeStorageKey(currentAgent)) || 'yolo';
|
currentMode = localStorage.getItem(getAgentModeStorageKey(currentAgent)) || 'yolo';
|
||||||
modeSelect.value = currentMode;
|
modeSelect.value = currentMode;
|
||||||
@@ -4160,6 +4172,7 @@
|
|||||||
|
|
||||||
function toggleAgentMenu() {
|
function toggleAgentMenu() {
|
||||||
if (!chatAgentMenu || !chatAgentBtn) return;
|
if (!chatAgentMenu || !chatAgentBtn) return;
|
||||||
|
if (chatAgentPicker?.hidden) return;
|
||||||
const willOpen = chatAgentMenu.hidden;
|
const willOpen = chatAgentMenu.hidden;
|
||||||
chatAgentMenu.hidden = !willOpen;
|
chatAgentMenu.hidden = !willOpen;
|
||||||
chatAgentBtn.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
|
chatAgentBtn.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
|
||||||
@@ -4199,8 +4212,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applySessionSnapshot(snapshot, options = {}) {
|
function applySessionSnapshot(snapshot, options = {}) {
|
||||||
if (!snapshot) return;
|
if (!snapshot) return false;
|
||||||
const snapshotAgent = normalizeAgent(snapshot.agent);
|
const snapshotAgent = normalizeAgent(snapshot.agent);
|
||||||
|
if (!isPrimaryUiAgent(snapshotAgent)) {
|
||||||
|
if (currentSessionId === snapshot.sessionId) resetChatView(PRIMARY_UI_AGENT);
|
||||||
|
renderSessionList();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (fileBrowserState && (fileBrowserState.sessionId !== snapshot.sessionId || (snapshot.cwd && fileBrowserState.rootPath !== snapshot.cwd))) {
|
if (fileBrowserState && (fileBrowserState.sessionId !== snapshot.sessionId || (snapshot.cwd && fileBrowserState.rootPath !== snapshot.cwd))) {
|
||||||
closeFileBrowser();
|
closeFileBrowser();
|
||||||
}
|
}
|
||||||
@@ -4260,10 +4278,11 @@
|
|||||||
if (snapshot.hasUnread && !options.suppressUnreadToast) {
|
if (snapshot.hasUnread && !options.suppressUnreadToast) {
|
||||||
showToast('后台任务已完成', snapshot.sessionId);
|
showToast('后台任务已完成', snapshot.sessionId);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncViewForAgent(agent, options = {}) {
|
function syncViewForAgent(agent, options = {}) {
|
||||||
const targetAgent = normalizeAgent(agent);
|
const targetAgent = normalizeUiAgent(agent);
|
||||||
const { preserveCurrent = true, loadLast = true } = options;
|
const { preserveCurrent = true, loadLast = true } = options;
|
||||||
setCurrentAgent(targetAgent);
|
setCurrentAgent(targetAgent);
|
||||||
closeUserOutlinePanel();
|
closeUserOutlinePanel();
|
||||||
@@ -4530,6 +4549,7 @@
|
|||||||
function showCachedSession(sessionId) {
|
function showCachedSession(sessionId) {
|
||||||
const snapshot = buildCachedSessionSnapshot(sessionId);
|
const snapshot = buildCachedSessionSnapshot(sessionId);
|
||||||
if (!snapshot) return false;
|
if (!snapshot) return false;
|
||||||
|
if (!isPrimaryUiAgent(snapshot.agent)) return false;
|
||||||
if (currentSessionId && currentSessionId !== sessionId) {
|
if (currentSessionId && currentSessionId !== sessionId) {
|
||||||
send({ type: 'detach_view' });
|
send({ type: 'detach_view' });
|
||||||
}
|
}
|
||||||
@@ -4537,12 +4557,17 @@
|
|||||||
closeCcwebPromptOutlinePanel();
|
closeCcwebPromptOutlinePanel();
|
||||||
clearSessionLoading();
|
clearSessionLoading();
|
||||||
touchSessionCache(sessionId);
|
touchSessionCache(sessionId);
|
||||||
applySessionSnapshot(snapshot, { immediate: true, suppressUnreadToast: true });
|
return applySessionSnapshot(snapshot, { immediate: true, suppressUnreadToast: true });
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openSession(sessionId, options = {}) {
|
function openSession(sessionId, options = {}) {
|
||||||
if (!sessionId) return;
|
if (!sessionId) return;
|
||||||
|
const meta = getSessionMeta(sessionId);
|
||||||
|
const cachedAgent = sessionCache.get(sessionId)?.snapshot?.agent;
|
||||||
|
if ((meta && !isPrimaryUiAgent(meta.agent)) || (!meta && cachedAgent && !isPrimaryUiAgent(cachedAgent))) {
|
||||||
|
renderSessionList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
closeUserOutlinePanel();
|
closeUserOutlinePanel();
|
||||||
closeCcwebPromptOutlinePanel();
|
closeCcwebPromptOutlinePanel();
|
||||||
if (options.forceSync) {
|
if (options.forceSync) {
|
||||||
@@ -5230,11 +5255,16 @@
|
|||||||
pendingNewSessionRequest = null;
|
pendingNewSessionRequest = null;
|
||||||
if (!matchesActiveLoad) clearSessionLoading();
|
if (!matchesActiveLoad) clearSessionLoading();
|
||||||
}
|
}
|
||||||
applySessionSnapshot(snapshot, {
|
const appliedSnapshot = applySessionSnapshot(snapshot, {
|
||||||
immediate: isBlockingSessionLoad(msg.sessionId),
|
immediate: isBlockingSessionLoad(msg.sessionId),
|
||||||
suppressUnreadToast: false,
|
suppressUnreadToast: false,
|
||||||
preserveStreaming: msg.sessionId === currentSessionId && msg.isRunning,
|
preserveStreaming: msg.sessionId === currentSessionId && msg.isRunning,
|
||||||
});
|
});
|
||||||
|
if (!appliedSnapshot) {
|
||||||
|
if (!msg.historyPending) cacheSessionSnapshot(snapshot);
|
||||||
|
if (matchesActiveLoad) clearSessionLoading(msg.sessionId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (msg.sessionId === currentSessionId) {
|
if (msg.sessionId === currentSessionId) {
|
||||||
setCurrentSessionRunningState(!!msg.isRunning);
|
setCurrentSessionRunningState(!!msg.isRunning);
|
||||||
}
|
}
|
||||||
@@ -9348,6 +9378,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showSettingsPanel() {
|
function showSettingsPanel() {
|
||||||
|
setCurrentAgent(PRIMARY_UI_AGENT);
|
||||||
if (isCodexLikeAgent(currentAgent)) {
|
if (isCodexLikeAgent(currentAgent)) {
|
||||||
showCodexSettingsPanel();
|
showCodexSettingsPanel();
|
||||||
return;
|
return;
|
||||||
@@ -9912,7 +9943,7 @@
|
|||||||
function requestNewSession(options = {}) {
|
function requestNewSession(options = {}) {
|
||||||
const cwd = options.cwd || null;
|
const cwd = options.cwd || null;
|
||||||
const rawCwd = options.rawCwd !== undefined ? options.rawCwd : (cwd || '');
|
const rawCwd = options.rawCwd !== undefined ? options.rawCwd : (cwd || '');
|
||||||
const agent = normalizeAgent(options.agent || currentAgent);
|
const agent = normalizeUiAgent(options.agent || currentAgent);
|
||||||
const mode = ['default', 'plan', 'yolo'].includes(options.mode) ? options.mode : currentMode;
|
const mode = ['default', 'plan', 'yolo'].includes(options.mode) ? options.mode : currentMode;
|
||||||
const model = typeof options.model === 'string' ? options.model.trim() : '';
|
const model = typeof options.model === 'string' ? options.model.trim() : '';
|
||||||
const title = typeof options.title === 'string' ? options.title.trim() : '';
|
const title = typeof options.title === 'string' ? options.title.trim() : '';
|
||||||
@@ -9945,8 +9976,7 @@
|
|||||||
let _onCwdSuggestions = null;
|
let _onCwdSuggestions = null;
|
||||||
|
|
||||||
function showNewSessionModal(options = {}) {
|
function showNewSessionModal(options = {}) {
|
||||||
const targetAgent = normalizeAgent(options.agent || currentAgent);
|
const targetAgent = normalizeUiAgent(options.agent || currentAgent);
|
||||||
const targetLabel = AGENT_LABELS[targetAgent] || AGENT_LABELS.claude;
|
|
||||||
const recentCwds = getRecentCwds();
|
const recentCwds = getRecentCwds();
|
||||||
const requestedMode = ['default', 'plan', 'yolo'].includes(options.mode) ? options.mode : currentMode;
|
const requestedMode = ['default', 'plan', 'yolo'].includes(options.mode) ? options.mode : currentMode;
|
||||||
let suggestionsRequested = false;
|
let suggestionsRequested = false;
|
||||||
@@ -9961,11 +9991,10 @@
|
|||||||
overlay.innerHTML = `
|
overlay.innerHTML = `
|
||||||
<div class="modal-panel">
|
<div class="modal-panel">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<span class="modal-title">新建 ${escapeHtml(targetLabel)} 会话</span>
|
<span class="modal-title">新建会话</span>
|
||||||
<button class="modal-close-btn" id="ns-close-btn">✕</button>
|
<button class="modal-close-btn" id="ns-close-btn">✕</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
${buildAgentContextCard(targetAgent, `当前将在 ${targetLabel} 区创建会话`, `新会话会直接进入 ${targetLabel} 模块,并只出现在 ${targetLabel} 会话列表中。`)}
|
|
||||||
<div class="modal-stack">
|
<div class="modal-stack">
|
||||||
<div>
|
<div>
|
||||||
<label class="modal-field-label" for="ns-cwd-input">工作目录</label>
|
<label class="modal-field-label" for="ns-cwd-input">工作目录</label>
|
||||||
|
|||||||
@@ -73,14 +73,6 @@
|
|||||||
<button id="menu-btn" class="menu-btn" title="菜单">☰</button>
|
<button id="menu-btn" class="menu-btn" title="菜单">☰</button>
|
||||||
<span id="chat-title" class="chat-title">新会话</span>
|
<span id="chat-title" class="chat-title">新会话</span>
|
||||||
<button id="chat-session-id-btn" class="chat-session-id-btn" type="button" title="复制当前会话 ID" hidden>ID</button>
|
<button id="chat-session-id-btn" class="chat-session-id-btn" type="button" title="复制当前会话 ID" hidden>ID</button>
|
||||||
<div class="chat-agent-picker">
|
|
||||||
<button id="chat-agent-btn" class="chat-agent-btn" type="button" aria-haspopup="menu" aria-expanded="false">Claude</button>
|
|
||||||
<div id="chat-agent-menu" class="chat-agent-menu" hidden>
|
|
||||||
<button type="button" class="chat-agent-option active" data-agent="claude">Claude</button>
|
|
||||||
<button type="button" class="chat-agent-option" data-agent="codex">Codex</button>
|
|
||||||
<button type="button" class="chat-agent-option" data-agent="codexapp">Codex App</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button id="chat-cwd" class="chat-cwd" type="button" hidden></button>
|
<button id="chat-cwd" class="chat-cwd" type="button" hidden></button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -173,6 +165,6 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.9.1/mermaid.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.9.1/mermaid.min.js"></script>
|
||||||
<script src="app.js?v=20260702-visible-no-rerender"></script>
|
<script src="app.js?v=20260705-codexapp-ui-agent"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1628,7 +1628,7 @@ body.session-loading-active {
|
|||||||
}
|
}
|
||||||
.chat-agent-picker {
|
.chat-agent-picker {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-flex;
|
display: none;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.chat-agent-btn {
|
.chat-agent-btn {
|
||||||
|
|||||||
@@ -647,6 +647,50 @@ function assertFrontendMcpReloadContract() {
|
|||||||
assert(source.includes('MCP 启动失败'), 'Frontend should expose a failed startup toast');
|
assert(source.includes('MCP 启动失败'), 'Frontend should expose a failed startup toast');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertFrontendPrimaryCodexAppUiContract() {
|
||||||
|
const source = fs.readFileSync(PUBLIC_APP_PATH, 'utf8');
|
||||||
|
const indexSource = fs.readFileSync(PUBLIC_INDEX_PATH, 'utf8');
|
||||||
|
const styleSource = fs.readFileSync(PUBLIC_STYLE_PATH, 'utf8');
|
||||||
|
const serverSource = fs.readFileSync(SERVER_PATH, 'utf8');
|
||||||
|
|
||||||
|
assert(!indexSource.includes('id="chat-agent-btn"'), 'Ordinary UI should not render an agent picker button');
|
||||||
|
assert(!indexSource.includes('id="chat-agent-menu"'), 'Ordinary UI should not render an agent picker menu');
|
||||||
|
assert(!indexSource.includes('class="chat-agent-picker"'), 'Ordinary UI should not render the agent picker container');
|
||||||
|
assert(
|
||||||
|
/\.chat-agent-picker\s*\{[\s\S]*?display:\s*none;/.test(styleSource),
|
||||||
|
'Stale cached agent picker markup should be hidden by CSS'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(source.includes("const PRIMARY_UI_AGENT = 'codexapp';"), 'Frontend should define Codex App as the primary UI agent');
|
||||||
|
assert(source.includes('const DEFAULT_AGENT = PRIMARY_UI_AGENT;'), 'Frontend default agent should point at the primary UI agent');
|
||||||
|
assert(source.includes('let currentAgent = DEFAULT_AGENT;'), 'Frontend should not initialize currentAgent from stale localStorage');
|
||||||
|
assert(source.includes("localStorage.setItem('cc-web-agent', currentAgent);"), 'Frontend should overwrite stale cc-web-agent storage with the primary UI agent');
|
||||||
|
assert(source.includes('currentAgent = normalizeUiAgent(agent);'), 'setCurrentAgent should coerce ordinary UI agent changes back to Codex App');
|
||||||
|
assert(source.includes('return sessions.filter((s) => isPrimaryUiAgent(s.agent));'), 'Session list should only expose Codex App sessions in ordinary UI');
|
||||||
|
assert(
|
||||||
|
/function applySessionSnapshot\(snapshot[\s\S]*?!isPrimaryUiAgent\(snapshotAgent\)[\s\S]*?return false;[\s\S]*?return true;/.test(source),
|
||||||
|
'Frontend should reject legacy Claude/Codex snapshots from the current view'
|
||||||
|
);
|
||||||
|
assert(source.includes('if (!isPrimaryUiAgent(snapshot.agent)) return false;'), 'Cached legacy sessions should not render in ordinary UI');
|
||||||
|
assert(source.includes('const agent = normalizeUiAgent(options.agent || currentAgent);'), 'Ordinary new-session UI should create Codex App sessions');
|
||||||
|
assert(source.includes('const targetAgent = normalizeUiAgent(options.agent || currentAgent);'), 'New-session modal should present the Codex App space');
|
||||||
|
assert(
|
||||||
|
/function showSettingsPanel\(\)[\s\S]*?setCurrentAgent\(PRIMARY_UI_AGENT\);[\s\S]*?showCodexSettingsPanel\(\);/.test(source),
|
||||||
|
'Settings button should route to existing Codex settings in ordinary UI'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(indexSource.includes('id="mode-select"'), 'Permission mode selector should remain visible');
|
||||||
|
assert(indexSource.includes('<option value="yolo">YOLO</option>'), 'YOLO permission mode should remain available');
|
||||||
|
assert(indexSource.includes('<option value="default">默认</option>'), 'Default permission mode should remain available');
|
||||||
|
assert(indexSource.includes('<option value="plan">Plan</option>'), 'Plan permission mode should remain available');
|
||||||
|
assert(indexSource.includes('Claude / Codex Web Chat'), 'Static login copy should keep existing Claude/Codex wording');
|
||||||
|
assert(indexSource.includes('开始与 Claude 对话'), 'Static welcome copy should keep existing Claude wording');
|
||||||
|
assert(
|
||||||
|
serverSource.includes("const VALID_AGENTS = new Set(['claude', 'codex', 'codexapp']);"),
|
||||||
|
'Server explicit agent support should remain available for API/MCP paths'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function assertSetTitleMcpContract() {
|
function assertSetTitleMcpContract() {
|
||||||
const serverSource = fs.readFileSync(SERVER_PATH, 'utf8');
|
const serverSource = fs.readFileSync(SERVER_PATH, 'utf8');
|
||||||
const frontendSource = fs.readFileSync(PUBLIC_APP_PATH, 'utf8');
|
const frontendSource = fs.readFileSync(PUBLIC_APP_PATH, 'utf8');
|
||||||
@@ -766,6 +810,7 @@ async function main() {
|
|||||||
assertFrontendMarkdownLinkContract();
|
assertFrontendMarkdownLinkContract();
|
||||||
assertMockCodexAppPromptUserNotTextTriggered();
|
assertMockCodexAppPromptUserNotTextTriggered();
|
||||||
assertFrontendMcpReloadContract();
|
assertFrontendMcpReloadContract();
|
||||||
|
assertFrontendPrimaryCodexAppUiContract();
|
||||||
assertSetTitleMcpContract();
|
assertSetTitleMcpContract();
|
||||||
assertSessionSwitchResilienceContract();
|
assertSessionSwitchResilienceContract();
|
||||||
|
|
||||||
@@ -1972,16 +2017,18 @@ async function main() {
|
|||||||
msg.type === 'session_message' &&
|
msg.type === 'session_message' &&
|
||||||
msg.sessionId === codexAppSession.sessionId &&
|
msg.sessionId === codexAppSession.sessionId &&
|
||||||
msg.message?.role === 'user' &&
|
msg.message?.role === 'user' &&
|
||||||
/我已回答 ccweb 提示的问题/.test(msg.message.content || '') &&
|
/表单答案/.test(msg.message.content || '') &&
|
||||||
/btnShortageReleaseConfirm/.test(msg.message.content || '')
|
/btnShortageReleaseConfirm/.test(msg.message.content || '')
|
||||||
));
|
));
|
||||||
assert(/使用 FineUI 弹窗,方便固定按钮 ID。/.test(promptAnswerMessage.message.content || ''), 'Prompt submission should become a normal user message with the free-form answer');
|
assert(/使用 FineUI 弹窗,方便固定按钮 ID。/.test(promptAnswerMessage.message.content || ''), 'Prompt submission should become a normal user message with the free-form answer');
|
||||||
|
assert(!/我已回答 ccweb 提示的问题/.test(promptAnswerMessage.message.content || ''), 'Prompt submission should not use the old first-person hard-coded prefix');
|
||||||
|
assert(!/ccweb 提示表单答案/.test(promptAnswerMessage.message.content || ''), 'Prompt submission should not expose the internal ccweb product name in the user message prefix');
|
||||||
const promptAnswerDelta = await nextMessage(messages, ws, (msg) => (
|
const promptAnswerDelta = await nextMessage(messages, ws, (msg) => (
|
||||||
msg.type === 'text_delta' &&
|
msg.type === 'text_delta' &&
|
||||||
msg.sessionId === codexAppSession.sessionId &&
|
msg.sessionId === codexAppSession.sessionId &&
|
||||||
/btnShortageReleaseConfirm/.test(msg.text || '')
|
/btnShortageReleaseConfirm/.test(msg.text || '')
|
||||||
));
|
));
|
||||||
assert(/我已回答 ccweb 提示的问题/.test(promptAnswerDelta.text || ''), 'Prompt submission should trigger a Codex App turn with the answer text');
|
assert(/表单答案/.test(promptAnswerDelta.text || ''), 'Prompt submission should trigger a Codex App turn with the answer text');
|
||||||
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
|
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId);
|
||||||
storedCodexApp = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
|
storedCodexApp = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
|
||||||
const storedPromptMessage = storedCodexApp.messages.find((message) => message.ccwebPrompt?.id === promptUserResult.body.promptId);
|
const storedPromptMessage = storedCodexApp.messages.find((message) => message.ccwebPrompt?.id === promptUserResult.body.promptId);
|
||||||
|
|||||||
@@ -4708,7 +4708,7 @@ function normalizeCcwebPromptUserAnswers(prompt, rawAnswers = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildCcwebPromptUserResponseText(prompt, answerList) {
|
function buildCcwebPromptUserResponseText(prompt, answerList) {
|
||||||
const lines = ['我已回答 ccweb 提示的问题:'];
|
const lines = ['表单答案:'];
|
||||||
if (prompt.title) {
|
if (prompt.title) {
|
||||||
lines.push('', `表单:${prompt.title}`);
|
lines.push('', `表单:${prompt.title}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user