feat: overhaul task board and cross-conversation workflows
This commit is contained in:
356
public/app.js
356
public/app.js
@@ -295,6 +295,12 @@
|
||||
savedSelection: null,
|
||||
};
|
||||
let usageDashboardRequestSeq = 0;
|
||||
const taskBoardViewState = {
|
||||
open: false,
|
||||
savedFocus: null,
|
||||
};
|
||||
let taskBoardController = null;
|
||||
let taskTrackingController = null;
|
||||
const usageEchartInstances = new Set();
|
||||
let usageChartResizeFrame = 0;
|
||||
let usageChartRefreshFrame = 0;
|
||||
@@ -318,6 +324,7 @@
|
||||
const pendingNotesByTarget = new Map();
|
||||
const queuedMessagesByTarget = new Map();
|
||||
const userMessageIndex = new Map();
|
||||
const codexAppSteerRecords = new Map();
|
||||
const pendingSlashDraftsByRequestId = new Map();
|
||||
const expandedOldSessionGroups = new Set();
|
||||
document.documentElement.dataset.dividerTime = showAgentDividerTime ? 'show' : 'hide';
|
||||
@@ -388,6 +395,11 @@
|
||||
const usageDashboardProjectEmpty = $('#usage-dashboard-project-empty');
|
||||
const usageDashboardSessionRows = $('#usage-dashboard-session-rows');
|
||||
const usageDashboardSessionEmpty = $('#usage-dashboard-session-empty');
|
||||
const taskBoardOpen = $('#task-board-open');
|
||||
const taskBoardPanel = $('#task-board-panel');
|
||||
const taskBoardClose = $('#task-board-close');
|
||||
const taskBoardRoot = $('#task-board-root');
|
||||
const taskTrackingControl = $('#task-tracking-control');
|
||||
const sessionList = $('#session-list');
|
||||
const chatHeader = chatMain?.querySelector('.chat-header') || null;
|
||||
const messagesWrap = chatMain?.querySelector('.messages-wrap') || null;
|
||||
@@ -1549,6 +1561,7 @@
|
||||
|
||||
function clearUserMessageIndex() {
|
||||
userMessageIndex.clear();
|
||||
codexAppSteerRecords.clear();
|
||||
}
|
||||
|
||||
function registerUserMessage(messageId, element, content, timestamp = '') {
|
||||
@@ -1562,6 +1575,73 @@
|
||||
});
|
||||
}
|
||||
|
||||
function cloneCodexAppSteerAttachments(attachments) {
|
||||
return Array.isArray(attachments)
|
||||
? attachments.map((attachment) => ({ ...attachment }))
|
||||
: [];
|
||||
}
|
||||
|
||||
function registerCodexAppSteerRecord(messageId, options = {}) {
|
||||
const id = String(messageId || '').trim();
|
||||
if (!id || !options.element) return null;
|
||||
const previous = codexAppSteerRecords.get(id) || {};
|
||||
const record = {
|
||||
id,
|
||||
element: options.element,
|
||||
text: String(options.text || ''),
|
||||
attachments: cloneCodexAppSteerAttachments(options.attachments),
|
||||
sessionId: options.sessionId || null,
|
||||
mode: options.mode || currentMode,
|
||||
agent: options.agent || currentAgent,
|
||||
status: options.status || previous.status || 'pending',
|
||||
message: options.message || previous.message || '',
|
||||
committed: previous.committed === true,
|
||||
inFlight: false,
|
||||
timestamp: options.timestamp || previous.timestamp || '',
|
||||
};
|
||||
codexAppSteerRecords.set(id, record);
|
||||
return record;
|
||||
}
|
||||
|
||||
function clearCodexAppSteerRecord(messageId) {
|
||||
const id = String(messageId || '').trim();
|
||||
if (!id) return;
|
||||
codexAppSteerRecords.delete(id);
|
||||
}
|
||||
|
||||
function commitCodexAppSteerMessage(record) {
|
||||
if (!record || record.committed) return false;
|
||||
const element = record.element;
|
||||
if (!element || record.sessionId !== currentSessionId) return false;
|
||||
if (element.dataset.sessionMessage === 'true') {
|
||||
record.committed = true;
|
||||
return false;
|
||||
}
|
||||
const messageIndex = currentSessionMessageCount;
|
||||
currentSessionMessageCount += 1;
|
||||
markSessionMessageElement(element, messageIndex);
|
||||
record.committed = true;
|
||||
updateUserOutlinePanel();
|
||||
return true;
|
||||
}
|
||||
|
||||
function registerCodexAppSteerSessionMessage(sessionId, message, element) {
|
||||
if (!message || message.role !== 'user' || !message.codexAppSteerStatus || !element) return null;
|
||||
const messageId = String(message.id || message.messageId || element.dataset.messageId || '').trim();
|
||||
if (!messageId) return null;
|
||||
return registerCodexAppSteerRecord(messageId, {
|
||||
element,
|
||||
text: message.content,
|
||||
attachments: message.attachments,
|
||||
sessionId,
|
||||
mode: message.mode || currentMode,
|
||||
agent: message.agent || currentAgent,
|
||||
status: message.codexAppSteerStatus,
|
||||
message: message.codexAppSteerMessage,
|
||||
timestamp: message.timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
function normalizeOutlineTitleHistory(history) {
|
||||
if (!Array.isArray(history)) return [];
|
||||
const normalized = [];
|
||||
@@ -2118,6 +2198,13 @@
|
||||
waitingReplyCount: Number(payload.waitingReplyCount || 0),
|
||||
failedReplyCount: Number(payload.failedReplyCount || 0),
|
||||
pendingReplies: Array.isArray(payload.pendingReplies) ? deepClone(payload.pendingReplies) : [],
|
||||
taskTracking: payload.taskTracking ? deepClone(payload.taskTracking) : {
|
||||
enabled: payload.taskTrackingEnabled === true,
|
||||
statusId: 'unassigned',
|
||||
version: 0,
|
||||
},
|
||||
taskTrackingEnabled: payload.taskTrackingEnabled === true
|
||||
|| payload.taskTracking?.enabled === true,
|
||||
historyTotal,
|
||||
historyBaseIndex,
|
||||
historyPending: !!payload.historyPending,
|
||||
@@ -5287,6 +5374,84 @@
|
||||
});
|
||||
}
|
||||
|
||||
function setTaskBoardUnderlyingInert(inert) {
|
||||
if (!chatMain) return;
|
||||
if (inert) chatMain.setAttribute('data-task-board-inert', 'true');
|
||||
else chatMain.removeAttribute('data-task-board-inert');
|
||||
if (messagesWrap) messagesWrap.toggleAttribute('inert', inert);
|
||||
if (inputArea) inputArea.toggleAttribute('inert', inert);
|
||||
if (chatHeader) chatHeader.toggleAttribute('inert', inert);
|
||||
}
|
||||
|
||||
function closeTaskBoard(options = {}) {
|
||||
if (!taskBoardPanel || !taskBoardViewState.open) return;
|
||||
taskBoardViewState.open = false;
|
||||
taskBoardPanel.hidden = true;
|
||||
taskBoardPanel.setAttribute('aria-hidden', 'true');
|
||||
taskBoardOpen?.setAttribute('aria-expanded', 'false');
|
||||
setTaskBoardUnderlyingInert(false);
|
||||
requestAnimationFrame(() => {
|
||||
if (options.restoreFocus !== false) {
|
||||
const target = taskBoardViewState.savedFocus;
|
||||
if (target?.isConnected && typeof target.focus === 'function') target.focus();
|
||||
else taskBoardOpen?.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openTaskBoard() {
|
||||
if (!taskBoardPanel || !taskBoardRoot || !window.CcwebTaskBoard) return;
|
||||
if (usageDashboardState.open) closeUsageDashboard({ restoreFocus: false });
|
||||
if (advancedSessionSearchState.open) closeAdvancedSessionSearch({ restoreFocus: false });
|
||||
taskBoardViewState.savedFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
||||
taskBoardViewState.open = true;
|
||||
taskBoardPanel.hidden = false;
|
||||
taskBoardPanel.setAttribute('aria-hidden', 'false');
|
||||
taskBoardOpen?.setAttribute('aria-expanded', 'true');
|
||||
setTaskBoardUnderlyingInert(true);
|
||||
if (isSidebarDrawerMode()) closeSidebar();
|
||||
if (!taskBoardController) {
|
||||
taskBoardController = window.CcwebTaskBoard.mount(taskBoardRoot, {
|
||||
send,
|
||||
openSession(sessionId) {
|
||||
closeTaskBoard({ restoreFocus: false });
|
||||
openSession(sessionId);
|
||||
},
|
||||
onError(error) { showToast(error?.message || '任务看板操作失败'); },
|
||||
});
|
||||
} else {
|
||||
taskBoardController.refresh();
|
||||
}
|
||||
requestAnimationFrame(() => taskBoardPanel.querySelector('button, input, select')?.focus());
|
||||
}
|
||||
|
||||
function syncTaskTrackingControl(snapshot = null) {
|
||||
if (!taskTrackingControl || !window.CcwebTaskBoard) return;
|
||||
const sessionId = snapshot?.sessionId || currentSessionId || '';
|
||||
const tracking = snapshot?.taskTracking || {};
|
||||
if (!sessionId) {
|
||||
taskTrackingControl.hidden = true;
|
||||
if (taskTrackingController) taskTrackingController.setState({ sessionId: '', disabled: true });
|
||||
return;
|
||||
}
|
||||
taskTrackingControl.hidden = false;
|
||||
const state = {
|
||||
sessionId,
|
||||
enabled: tracking.enabled === true || snapshot?.taskTrackingEnabled === true,
|
||||
version: Number.isFinite(Number(tracking.version)) ? Number(tracking.version) : null,
|
||||
disabled: false,
|
||||
};
|
||||
if (!taskTrackingController) {
|
||||
taskTrackingController = window.CcwebTaskBoard.renderTrackingControl(taskTrackingControl, {
|
||||
...state,
|
||||
send,
|
||||
onError(error) { showToast(error?.message || '保存任务跟踪设置失败'); },
|
||||
});
|
||||
} else {
|
||||
taskTrackingController.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
function handleUsageStatisticsResult(msg) {
|
||||
const requestId = String(msg?.requestId || '');
|
||||
if (!requestId || requestId !== usageDashboardState.requestId) return;
|
||||
@@ -5703,6 +5868,7 @@
|
||||
closeCcwebPromptOutlinePanel();
|
||||
closeFileBrowser();
|
||||
currentSessionId = null;
|
||||
syncTaskTrackingControl(null);
|
||||
loadedHistorySessionId = null;
|
||||
currentSessionMessageCount = 0;
|
||||
currentOutlineTitleHistory = [];
|
||||
@@ -5762,6 +5928,7 @@
|
||||
activeTodoCallTargets.clear();
|
||||
}
|
||||
currentSessionId = snapshot.sessionId;
|
||||
syncTaskTrackingControl(snapshot);
|
||||
loadedHistorySessionId = snapshot.sessionId;
|
||||
currentOutlineTitleHistory = normalizeOutlineTitleHistory(snapshot.titleHistory);
|
||||
currentSessionMessageCount = Math.max(
|
||||
@@ -6130,6 +6297,7 @@
|
||||
|
||||
function openSession(sessionId, options = {}) {
|
||||
if (!sessionId) return;
|
||||
if (taskBoardViewState.open) closeTaskBoard({ restoreFocus: false });
|
||||
if (usageDashboardState.open) closeUsageDashboard({ restoreFocus: false });
|
||||
const meta = getSessionMeta(sessionId);
|
||||
const cachedAgent = sessionCache.get(sessionId)?.snapshot?.agent;
|
||||
@@ -6728,7 +6896,46 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleTaskBoardProtocolMessage(msg) {
|
||||
const taskMessageTypes = new Set([
|
||||
'task_board_result',
|
||||
'task_board_event',
|
||||
'task_tracking_result',
|
||||
'task_status_result',
|
||||
'task_status_definitions_result',
|
||||
'task_archive_result',
|
||||
]);
|
||||
if (!taskMessageTypes.has(msg?.type)) return false;
|
||||
|
||||
taskBoardController?.handleMessage(msg);
|
||||
taskTrackingController?.handleMessage(msg);
|
||||
|
||||
const task = msg.task && typeof msg.task === 'object' ? msg.task : null;
|
||||
const sessionId = String(task?.sessionId || msg.sessionId || '');
|
||||
if (task?.taskTracking && sessionId) {
|
||||
const listItem = sessions.find((session) => session.id === sessionId);
|
||||
if (listItem) {
|
||||
listItem.taskTracking = deepClone(task.taskTracking);
|
||||
listItem.taskTrackingEnabled = task.taskTracking.enabled === true;
|
||||
}
|
||||
const cached = sessionCache.get(sessionId)?.snapshot;
|
||||
if (cached) {
|
||||
cached.taskTracking = deepClone(task.taskTracking);
|
||||
cached.taskTrackingEnabled = task.taskTracking.enabled === true;
|
||||
}
|
||||
if (sessionId === currentSessionId) {
|
||||
syncTaskTrackingControl({
|
||||
sessionId,
|
||||
taskTracking: task.taskTracking,
|
||||
taskTrackingEnabled: task.taskTracking.enabled === true,
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleServerMessage(msg) {
|
||||
if (handleTaskBoardProtocolMessage(msg)) return;
|
||||
switch (msg.type) {
|
||||
case 'auth_result':
|
||||
if (msg.success) {
|
||||
@@ -6928,9 +7135,10 @@
|
||||
case 'session_message':
|
||||
if (msg.sessionId && msg.message) {
|
||||
const isCrossConversationReply = !!msg.message.crossConversation?.replyToRequestId;
|
||||
const isProvisionalCodexAppSteer = !!msg.message.codexAppSteerStatus;
|
||||
updateCachedSession(msg.sessionId, (snapshot) => {
|
||||
snapshot.messages = Array.isArray(snapshot.messages) ? snapshot.messages : [];
|
||||
snapshot.messages.push(deepClone(msg.message));
|
||||
if (!isProvisionalCodexAppSteer) snapshot.messages.push(deepClone(msg.message));
|
||||
snapshot.updated = msg.message.timestamp || new Date().toISOString();
|
||||
if (isCrossConversationReply) {
|
||||
snapshot.readyReplyCount = Math.max(0, Number(snapshot.readyReplyCount || 0) - 1);
|
||||
@@ -6953,13 +7161,16 @@
|
||||
}
|
||||
}
|
||||
if (msg.sessionId === currentSessionId && msg.message) {
|
||||
const messageIndex = currentSessionMessageCount;
|
||||
currentSessionMessageCount += 1;
|
||||
const isProvisionalCodexAppSteer = !!msg.message.codexAppSteerStatus;
|
||||
const messageIndex = isProvisionalCodexAppSteer ? null : currentSessionMessageCount;
|
||||
if (!isProvisionalCodexAppSteer) currentSessionMessageCount += 1;
|
||||
collectClosedCollabAgentIds([msg.message]).forEach((id) => closedCollabAgentIds.add(id));
|
||||
const welcome = messagesDiv.querySelector('.welcome-msg');
|
||||
if (welcome) welcome.remove();
|
||||
const shouldFollow = !(currentSessionRunning || isGenerating) || isNearBottom();
|
||||
messagesDiv.appendChild(buildMsgElement(msg.message, messageIndex));
|
||||
const element = buildMsgElement(msg.message, messageIndex);
|
||||
messagesDiv.appendChild(element);
|
||||
registerCodexAppSteerSessionMessage(msg.sessionId, msg.message, element);
|
||||
followOutputIfNeeded(shouldFollow);
|
||||
setCurrentSessionRunningState(!!getSessionMeta(currentSessionId)?.isRunning);
|
||||
renderPendingCcwebPrompts({ scroll: false });
|
||||
@@ -7231,6 +7442,7 @@
|
||||
title: request.title,
|
||||
branchSourceSessionId: request.branchSourceSessionId,
|
||||
branchMessageIndex: request.branchMessageIndex,
|
||||
taskTrackingEnabled: request.taskTrackingEnabled === true,
|
||||
createCwd: true,
|
||||
requestId: request.requestId,
|
||||
});
|
||||
@@ -7244,6 +7456,7 @@
|
||||
title: request.title,
|
||||
branchSourceSessionId: request.branchSourceSessionId,
|
||||
branchMessageIndex: request.branchMessageIndex,
|
||||
taskTrackingEnabled: request.taskTrackingEnabled === true,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -7490,13 +7703,81 @@
|
||||
return '引导中...';
|
||||
}
|
||||
|
||||
function retryCodexAppSteerMessage(messageId) {
|
||||
const id = String(messageId || '').trim();
|
||||
const record = id ? codexAppSteerRecords.get(id) : null;
|
||||
if (!record || record.status !== 'failed' || record.inFlight) return false;
|
||||
if (record.sessionId && currentSessionId && record.sessionId !== currentSessionId) {
|
||||
appendError('该失败项不属于当前会话,无法重试。');
|
||||
setCodexAppSteerStatusElement(record.element, 'failed', record.message || '插入失败');
|
||||
return false;
|
||||
}
|
||||
if (!isGenerating || !currentSessionRunning || !isCodexAppAgent(currentAgent)) {
|
||||
appendError('当前对话已结束,无法在原 turn 中重试插入。');
|
||||
setCodexAppSteerStatusElement(record.element, 'failed', record.message || '插入失败');
|
||||
return false;
|
||||
}
|
||||
if (!ws || ws.readyState !== 1) {
|
||||
appendError('WebSocket 已断开,请恢复连接后重试。');
|
||||
setCodexAppSteerStatusElement(record.element, 'failed', record.message || '插入失败');
|
||||
return false;
|
||||
}
|
||||
|
||||
record.inFlight = true;
|
||||
setCodexAppSteerStatusElement(record.element, 'pending', '引导中...');
|
||||
try {
|
||||
send({
|
||||
type: 'message',
|
||||
text: record.text,
|
||||
attachments: cloneCodexAppSteerAttachments(record.attachments),
|
||||
sessionId: record.sessionId,
|
||||
mode: record.mode,
|
||||
agent: record.agent,
|
||||
clientMessageId: id,
|
||||
});
|
||||
return true;
|
||||
} catch (err) {
|
||||
record.inFlight = false;
|
||||
record.status = 'failed';
|
||||
record.message = record.message || '插入失败';
|
||||
setCodexAppSteerStatusElement(record.element, 'failed', record.message);
|
||||
appendError(err?.message || '重试发送失败。');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteCodexAppSteerMessage(messageId) {
|
||||
const id = String(messageId || '').trim();
|
||||
if (!id) return false;
|
||||
const record = codexAppSteerRecords.get(id);
|
||||
const indexed = userMessageIndex.get(id);
|
||||
const element = record?.element || indexed?.element || messagesDiv.querySelector(`[data-message-id="${cssEscape(id)}"]`);
|
||||
const status = record?.status || element?.querySelector('.codex-steer-status')?.dataset.status;
|
||||
if (status !== 'failed') return false;
|
||||
if (record?.inFlight) return false;
|
||||
if (element) element.remove();
|
||||
clearCodexAppSteerRecord(id);
|
||||
userMessageIndex.delete(id);
|
||||
updateUserOutlinePanel();
|
||||
updateScrollbar();
|
||||
return true;
|
||||
}
|
||||
|
||||
function setCodexAppSteerStatusElement(element, status, message) {
|
||||
if (!element) return false;
|
||||
const normalized = ['pending', 'inserted', 'failed'].includes(status) ? status : 'pending';
|
||||
const messageId = String(element.dataset.messageId || '').trim();
|
||||
const record = messageId ? codexAppSteerRecords.get(messageId) : null;
|
||||
if (record) {
|
||||
record.status = normalized;
|
||||
record.message = message || codexAppSteerStatusLabel(normalized);
|
||||
if (normalized !== 'pending') record.inFlight = false;
|
||||
}
|
||||
element.classList.add('codex-steer-message');
|
||||
element.classList.toggle('codex-steer-pending', normalized === 'pending');
|
||||
element.classList.toggle('codex-steer-inserted', normalized === 'inserted');
|
||||
element.classList.toggle('codex-steer-failed', normalized === 'failed');
|
||||
element.setAttribute('aria-busy', normalized === 'pending' ? 'true' : 'false');
|
||||
const bubble = element.querySelector('.msg-bubble');
|
||||
if (!bubble) return false;
|
||||
let statusEl = bubble.querySelector('.codex-steer-status');
|
||||
@@ -7506,7 +7787,45 @@
|
||||
bubble.appendChild(statusEl);
|
||||
}
|
||||
statusEl.dataset.status = normalized;
|
||||
statusEl.setAttribute('role', 'status');
|
||||
statusEl.setAttribute('aria-live', 'polite');
|
||||
statusEl.textContent = message || codexAppSteerStatusLabel(normalized);
|
||||
let actions = bubble.querySelector('.codex-steer-actions');
|
||||
if (normalized !== 'failed') {
|
||||
if (actions) actions.remove();
|
||||
if (normalized === 'inserted' && record) commitCodexAppSteerMessage(record);
|
||||
return true;
|
||||
}
|
||||
if (!actions) {
|
||||
actions = document.createElement('div');
|
||||
actions.className = 'codex-steer-actions';
|
||||
const retryButton = document.createElement('button');
|
||||
retryButton.type = 'button';
|
||||
retryButton.className = 'codex-steer-action codex-steer-retry';
|
||||
retryButton.textContent = '重试';
|
||||
retryButton.setAttribute('aria-label', '重试插入此消息');
|
||||
retryButton.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
retryCodexAppSteerMessage(messageId);
|
||||
});
|
||||
const deleteButton = document.createElement('button');
|
||||
deleteButton.type = 'button';
|
||||
deleteButton.className = 'codex-steer-action codex-steer-delete';
|
||||
deleteButton.textContent = '删除';
|
||||
deleteButton.setAttribute('aria-label', '删除失败插入项');
|
||||
deleteButton.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
deleteCodexAppSteerMessage(messageId);
|
||||
});
|
||||
actions.appendChild(retryButton);
|
||||
actions.appendChild(deleteButton);
|
||||
bubble.appendChild(actions);
|
||||
}
|
||||
actions.querySelectorAll('button').forEach((button) => {
|
||||
button.disabled = !!record?.inFlight;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10883,12 +11202,16 @@
|
||||
} else {
|
||||
messagesDiv.appendChild(element);
|
||||
}
|
||||
if (currentSessionId) {
|
||||
const messageIndex = currentSessionMessageCount;
|
||||
currentSessionMessageCount += 1;
|
||||
markSessionMessageElement(element, messageIndex);
|
||||
}
|
||||
registerUserMessage(messageId, element, text, timestamp);
|
||||
registerCodexAppSteerRecord(messageId, {
|
||||
element,
|
||||
text,
|
||||
attachments,
|
||||
sessionId: currentSessionId,
|
||||
mode: currentMode,
|
||||
agent: currentAgent,
|
||||
timestamp,
|
||||
});
|
||||
updateUserOutlinePanel();
|
||||
if (shouldFollow) {
|
||||
scrollToBottom();
|
||||
@@ -11154,6 +11477,11 @@
|
||||
setUsageDashboardFeatureEnabled(false);
|
||||
}
|
||||
|
||||
if (taskBoardOpen && taskBoardPanel && taskBoardRoot) {
|
||||
taskBoardOpen.addEventListener('click', openTaskBoard);
|
||||
taskBoardClose?.addEventListener('click', () => closeTaskBoard());
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key.toLowerCase() === 'f') {
|
||||
event.preventDefault();
|
||||
@@ -11170,6 +11498,11 @@
|
||||
closeUsageDashboard();
|
||||
return;
|
||||
}
|
||||
if (event.key === 'Escape' && taskBoardViewState.open) {
|
||||
event.preventDefault();
|
||||
closeTaskBoard();
|
||||
return;
|
||||
}
|
||||
if (event.key === 'Escape' && advancedSessionSearchState.open) {
|
||||
event.preventDefault();
|
||||
closeAdvancedSessionSearch();
|
||||
@@ -12563,6 +12896,8 @@
|
||||
const branchMessageIndex = Number.isFinite(Number(options.branchMessageIndex))
|
||||
? Number(options.branchMessageIndex)
|
||||
: null;
|
||||
const taskTrackingEnabled = options.taskTrackingEnabled === true
|
||||
|| options.taskTracking?.enabled === true;
|
||||
const requestId = createSessionSwitchRequestId('new');
|
||||
pendingNewSessionRequest = {
|
||||
cwd,
|
||||
@@ -12573,6 +12908,7 @@
|
||||
title,
|
||||
branchSourceSessionId,
|
||||
branchMessageIndex,
|
||||
taskTrackingEnabled,
|
||||
requestId,
|
||||
};
|
||||
if (cwd) saveRecentCwd(cwd);
|
||||
@@ -12581,6 +12917,7 @@
|
||||
if (title) payload.title = title;
|
||||
if (branchSourceSessionId) payload.branchSourceSessionId = branchSourceSessionId;
|
||||
if (branchMessageIndex !== null) payload.branchMessageIndex = branchMessageIndex;
|
||||
if (taskTrackingEnabled) payload.taskTrackingEnabled = true;
|
||||
send(payload);
|
||||
}
|
||||
|
||||
@@ -12717,6 +13054,7 @@
|
||||
title: options.title || '',
|
||||
branchSourceSessionId: options.branchSourceSessionId || '',
|
||||
branchMessageIndex: options.branchMessageIndex,
|
||||
taskTrackingEnabled: options.taskTrackingEnabled === true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user