更新对话标题和 MCP 描述并重新打包 CentOS 7 发布包
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
{"file":".trellis/spec/frontend/state-management.md","reason":"检查当前会话、后台更新与切换隔离"}
|
||||
{"file":".trellis/spec/frontend/quality-guidelines.md","reason":"检查语法和行为验证"}
|
||||
@@ -0,0 +1,9 @@
|
||||
# 调查记录
|
||||
|
||||
- 项目为原生 JavaScript 前端,入口 public/index.html 默认 title 为 CC-Web。
|
||||
- 初步索引搜索未发现 document.title 动态更新逻辑。
|
||||
- codebase-memory 索引状态 ready。
|
||||
- public/app.js 中 resetChatView、applySessionSnapshot、handleServerMessage 的 title_updated 分支以及聊天标题编辑完成逻辑直接写入 chatTitle.textContent,应统一维护标签页标题。
|
||||
- 实际事件名为 session_renamed;session_list 当前不主动刷新聊天标题,需要同步当前会话名称且避开编辑中的草稿。
|
||||
- 服务端每次计算 app.js 内容哈希并用于入口页版本,可刷新页面加载本次改动,无需重启服务。
|
||||
- 主代理读取源码片段时 codebase-memory 出现 Transport closed,已按已定位符号用本地读取降级;实现子代理仍可访问索引。
|
||||
@@ -0,0 +1,2 @@
|
||||
{"file":".trellis/spec/frontend/state-management.md","reason":"沿用当前会话状态更新链路"}
|
||||
{"file":".trellis/spec/frontend/quality-guidelines.md","reason":"遵守原生前端与静态资源版本约定"}
|
||||
5
.trellis/tasks/10-19-conversation-document-title/prd.md
Normal file
5
.trellis/tasks/10-19-conversation-document-title/prd.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# 当前对话同步浏览器标题
|
||||
|
||||
浏览器标签页的 title 随当前打开的对话名称更新;切换对话、自动生成标题和手动重命名后保持同步。没有当前对话时使用 CC-Web。复用现有当前对话标题入口,不改变页面视觉样式。
|
||||
|
||||
验收:检查初始加载、切换、重命名、后台会话更新与无当前会话的标题表现;完成语法检查与必要行为验证。
|
||||
23
.trellis/tasks/10-19-conversation-document-title/progress.md
Normal file
23
.trellis/tasks/10-19-conversation-document-title/progress.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 进度记录
|
||||
|
||||
- 已确认需求是浏览器标签页标题随当前对话名称同步。
|
||||
- 已读取项目约定并建立任务记录、计划和 CSV;验证探索交由只读子代理并行进行。
|
||||
- todo-list-csv 技能未安装;按项目约定直接维护 CSV。
|
||||
- 已定位 public/app.js 的会话快照、列表刷新、重命名和重置路径;实现子代理仅修改 app.js,主代理负责文档与验证。
|
||||
- 只读验证发现现有回归没有 document.title 行为断言;采用临时浏览器验证,不新增长期测试文件。
|
||||
- app.js 已通过 setChatTitle 统一维护页头与浏览器标题,覆盖载入、重命名、列表刷新与重置;编辑中不由列表刷新覆盖草稿。
|
||||
- node --check public/app.js 通过。
|
||||
- Chromium 149.0.7827.55 通过 11 项真实 DOM 行为检查:初始、打开、切换、当前重命名、后台隔离、列表同步、编辑草稿、提交、取消、无名称回退与重置默认;无页面脚本异常。
|
||||
- 浏览器使用本地夹具、模拟通信和临时暴露入口,未访问真实会话或调用生产 API;临时脚本在 /tmp,未加入项目。
|
||||
- 独立审查通过:currentSessionId 变化均覆盖标题更新,后台会话隔离正确,Escape 恢复后通过 blur 同步;git diff --check 通过。
|
||||
- 已评估规范更新:本次沿用既有会话状态更新模式,无需新增规范条目。
|
||||
- 工作完成,无需重启服务;用户刷新页面即可加载更新。
|
||||
|
||||
## 后续交付
|
||||
|
||||
- 按用户修正,标签页仅显示当前对话名称,已去掉 CC-Web 后缀。
|
||||
- 已按用户原文更新设置标题、发送消息、列出对话、更新计划、创建持久对话和多问题表单六项 MCP 工具描述。
|
||||
- 已重启 ccweb,并在当前模型工具列表确认六项新描述生效。
|
||||
- 用户要求重新打包并提交推送全部修改,不再进行额外审计。
|
||||
- 使用本地 Bun 1.4.0 按 bun-linux-x64-baseline 目标重新生成发布包;必要语法检查、可执行文件 MCP initialize、压缩包完整性及前端源码一致性验证均通过。
|
||||
- 发布包 42.96 MiB,SHA-256:2ee61a827b56f2ff538ced64c344ff73470e3df042db61d2f9360d67eebef49f。
|
||||
26
.trellis/tasks/10-19-conversation-document-title/task.json
Normal file
26
.trellis/tasks/10-19-conversation-document-title/task.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "conversation-document-title",
|
||||
"name": "conversation-document-title",
|
||||
"title": "当前对话同步浏览器标题",
|
||||
"description": "",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "shiyue",
|
||||
"assignee": "shiyue",
|
||||
"createdAt": "2026-10-19",
|
||||
"completedAt": "2026-10-19",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# 任务计划
|
||||
|
||||
1. [completed] 定位当前对话名称与浏览器标题的更新入口。
|
||||
2. [completed] 实现浏览器标题随当前对话同步。
|
||||
3. [completed] 验证切换、重命名和默认标题并收尾。
|
||||
|
||||
## 约束
|
||||
|
||||
只修改相关前端逻辑,不重启正在承载其他运行会话的服务。
|
||||
|
||||
## 工具异常
|
||||
|
||||
- codebase-memory 的 get_code_snippet 在主代理端连接关闭,已使用本地文件读取;子代理端索引正常。
|
||||
Binary file not shown.
@@ -16,7 +16,7 @@ const CCWEB_REPLY_MODES = Object.freeze({
|
||||
ONE_WAY: 'one_way',
|
||||
RETURN_AND_CONTINUE: 'return_and_continue',
|
||||
});
|
||||
const CCWEB_SEND_MESSAGE_DESCRIPTION = '向指定 ccweb 对话发送一条消息,并以“来自某对话”的气泡在目标对话中展示。必须填写 replyMode:仅当来源不需要目标结果时使用 one_way;涉及分析、实现、测试、验收、完成后汇报或来源后续依赖目标结果时必须使用 return_and_continue。两种模式的工具调用都会立即返回,不阻塞也不等待目标对话完成;return_and_continue 只表示目标完成后由系统异步回传并触发来源继续运行,不表示当前调用需要等待。调用后不要使用 sleep、不要轮询等待,也不要反复查询 pending reply;继续当前工作或结束本轮即可。';
|
||||
const CCWEB_SEND_MESSAGE_DESCRIPTION = '向指定对话发送一条消息,并以“来自某对话”的气泡在目标对话中展示。必须填写 replyMode:仅当来源不需要目标结果时使用 one_way;涉及分析、实现、测试、验收、完成后汇报或来源后续依赖目标结果时必须使用 return_and_continue。两种模式的工具调用都会立即返回,不阻塞也不等待目标对话完成;return_and_continue 只表示目标完成后由系统异步回传并触发来源继续运行,不表示当前调用需要等待。调用后不要使用 sleep、不要轮询等待,也不要反复查询 pending reply;继续当前工作或结束本轮即可。';
|
||||
const CODEX_APP_COMMUNICATION_TOOL_NAMES = new Set([
|
||||
'ccweb_list_conversations',
|
||||
'ccweb_list_user_inputs',
|
||||
@@ -55,7 +55,7 @@ const TOOLS = [
|
||||
},
|
||||
{
|
||||
name: 'ccweb_list_conversations',
|
||||
description: '列出当前 ccweb 中可投递消息的对话。默认返回全部对话;scope=children 时只返回当前来源对话通过 ccweb_create_conversation 直接创建的持久子对话。只返回 ID、标题、Agent、运行状态和更新时间,不返回对话正文。',
|
||||
description: '列出当前对话列表中可投递消息的对话。默认返回全部对话;scope=children 时只返回当前来源对话通过 ccweb_create_conversation 直接创建的持久子对话。只返回 ID、标题、Agent、运行状态和更新时间,不返回对话正文。',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -112,7 +112,7 @@ const TOOLS = [
|
||||
},
|
||||
{
|
||||
name: 'ccweb_set_title',
|
||||
description: '设置当前 ccweb 对话标题。只作用于当前来源对话;用户手动重命名后会成功返回但忽略,不再覆盖用户标题。',
|
||||
description: '设置当前对话标题,新对话明确需求后调用一次;普通进展、子步骤、实现细节都不要改名,只有主要目标发生明显变化才再次调用。',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -128,7 +128,7 @@ const TOOLS = [
|
||||
},
|
||||
{
|
||||
name: 'ccweb_update_plan',
|
||||
description: '当原生 update_plan 工具不可用时,在当前 ccweb 对话展示并更新多步骤计划。每次传入完整计划;开始、完成步骤时重新调用以同步状态。简单任务无需调用。',
|
||||
description: '当原生 update_plan 工具不可用时,优先调用此工具展示并更新多步骤计划。每次传入完整计划;开始、完成步骤时重新调用以同步状态。简单任务无需调用。',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -155,7 +155,7 @@ const TOOLS = [
|
||||
},
|
||||
{
|
||||
name: 'ccweb_create_conversation',
|
||||
description: '创建一个新的 ccweb 持久对话。Agent 固定继承来源对话,不作为参数指定;只用于需要在会话列表中长期追踪、后续可继续对话的工作流;一次性并行研究应优先使用子代能力。工具调用会立即返回。启用 requestReply 后,默认由系统异步回传结果;除非用户明确要求轮询,否则不主动轮询等待。',
|
||||
description: '创建一个新的持久对话。只用于需要在会话列表中长期追踪、后续可继续对话的工作流;一次性并行研究应优先使用子代能力。工具调用会立即返回。启用 requestReply 后,默认由系统异步回传结果;任何尝试轮询等待持久对话返回的行为都是禁止的',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -241,7 +241,7 @@ const TOOLS = [
|
||||
},
|
||||
{
|
||||
name: 'ccweb_prompt_user',
|
||||
description: '在当前来源 ccweb 对话前台渲染一个多问题表单。工具会立即返回,不等待用户;用户提交后,ccweb 会把问题、选择和答案作为一条普通用户消息发回当前对话。',
|
||||
description: '调用此工具实时渲染一个多问题表单,工具会立即返回一个待定状态;用户提交后,会把问题、选择和答案作为一普通用户消息发回当前对话。',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
||||
@@ -7142,6 +7142,11 @@
|
||||
chatAgentBtn.setAttribute('aria-expanded', willOpen ? 'true' : 'false');
|
||||
}
|
||||
|
||||
function setChatTitle(title) {
|
||||
chatTitle.textContent = title || '新会话';
|
||||
document.title = currentSessionId ? chatTitle.textContent : 'CC-Web';
|
||||
}
|
||||
|
||||
function resetChatView(agent) {
|
||||
abortToolDetailRequests();
|
||||
clearPendingMissingSessionConfirmation();
|
||||
@@ -7177,7 +7182,7 @@
|
||||
collabAgentIdsByToolUseId = new Map();
|
||||
closedCollabAgentIdsByToolUseId = new Map();
|
||||
updateGenerationControls();
|
||||
chatTitle.textContent = '新会话';
|
||||
setChatTitle('新会话');
|
||||
updateSessionIdBadge();
|
||||
updateCwdBadge();
|
||||
updateReloadMcpButtonUI();
|
||||
@@ -7235,7 +7240,7 @@
|
||||
(snapshot.messages || []).length,
|
||||
);
|
||||
setLastSessionForAgent(snapshot.agent, currentSessionId);
|
||||
chatTitle.textContent = snapshot.title || '新会话';
|
||||
setChatTitle(snapshot.title);
|
||||
updateSessionIdBadge();
|
||||
setCurrentAgent(snapshotAgent);
|
||||
migratePendingNotesToSession(snapshot.sessionId, snapshotAgent);
|
||||
@@ -8554,7 +8559,11 @@
|
||||
reconcileSessionCacheWithSessions();
|
||||
renderSessionList();
|
||||
if (currentSessionId) {
|
||||
setCurrentSessionRunningState(!!getSessionMeta(currentSessionId)?.isRunning);
|
||||
const currentSession = getSessionMeta(currentSessionId);
|
||||
setCurrentSessionRunningState(!!currentSession?.isRunning);
|
||||
if (currentSession && chatTitle.contentEditable !== 'true') {
|
||||
setChatTitle(currentSession.title);
|
||||
}
|
||||
}
|
||||
if (pendingInitialSessionLoad) {
|
||||
pendingInitialSessionLoad = false;
|
||||
@@ -8884,7 +8893,7 @@
|
||||
}
|
||||
});
|
||||
if (msg.sessionId === currentSessionId) {
|
||||
chatTitle.textContent = msg.title;
|
||||
setChatTitle(msg.title);
|
||||
if (msg.titleEvent) {
|
||||
currentOutlineTitleHistory = normalizeOutlineTitleHistory([...currentOutlineTitleHistory, msg.titleEvent]);
|
||||
updateUserOutlinePanel();
|
||||
@@ -12763,7 +12772,7 @@
|
||||
chatTitle.style.overflow = '';
|
||||
chatTitle.style.textOverflow = '';
|
||||
const newTitle = chatTitle.textContent.trim() || originalText;
|
||||
chatTitle.textContent = newTitle;
|
||||
setChatTitle(newTitle);
|
||||
if (save && newTitle !== originalText && currentSessionId) {
|
||||
send({ type: 'rename_session', sessionId: currentSessionId, title: newTitle });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user