diff --git a/docs/todo.md b/docs/todo.md index 9d4be81..4e74768 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -329,8 +329,8 @@ graph TD - [x] **AIC-FIX-17-P0-1** — 流式 watchdog legacy 路径 `convStates.clear()` 全局误杀 → `delete(state.activeConversationId)` ✅ - [x] **AIC-FIX-17-P0-2** — 审批计时器切/删会话不清 → switch/delete 入口 `clearAllApprovalTimers()` + 注释修正 ✅ -- [ ] **AIC-FIX-17-P1-1~11** — P1 队列/互斥/modelOverride/死代码/缓存/防重入/删除回落(待后续批次) -- [ ] **AIC-FIX-17-P2** — P2 健壮性项(待后续批次) +- [x] **AIC-FIX-17-P1-1~11** ✅ 已销账(2026-08-15 核验,1 agent 全量核验 + 主代 4 项抽查源码属实):P1-1/3/4/5(queue/modelOverride/spans/_lastDelta per-conv,F-09 收尾)/ P1-2 drainQueue 互斥 `_drainingConvs` Set(useAiSend:274)/ P1-6 flushCurrentText 守卫 / P1-7 MessageItem 收敛仅 user 角色 / P1-8 _blockCache LRU 300+切会话 resetStreamCache / P1-9 指纹 watch 替代 deep / P1-10 approving 防重入前置(useToolApproval:133)/ P1-11 deleteConversation 相邻回落(useAiConversations:520)。余「MessageList 内联渲染组件化」「缓存主动失效」为优化空间非缺陷 +- [x] **AIC-FIX-17-P2** ✅ 已销账(2026-08-15):7 条中 5 条核验为此前批次已修(ApprovalOverlay 响应式冷却/aiShared 对称收敛/flash watch/maximized 三元/emit 类型),2 条本批落地(tailSeq 注释与实现对齐 useStreamRenderer:142-196、isCompressing 单例补 known limitation 注释 useAiContext:28) - [x] **AIC-FIX-17-根因** ✅ **2026-08-07 核验销账**(queue/modelOverride/审批/_lastDelta 均已 per-conv) — F-09 per-conv 收尾(queue / modelOverride / _approvalTimers / _lastDelta 单例化) --- @@ -386,7 +386,7 @@ graph TD - [x] ✅ **P1-f** cmd 闪烁 N² — **已落地(2026-08-09 141777b)**:module.rs 新增仓库级 git status 缓存(GIT_STATUS_CACHE,key=仓库根 path,TTL 5s,锁内不跑 git,非 git 不缓存;get_module_file_tree + get_module_git_status 两处收口;删除/更新 module 清缓存);前端联动未做(5s TTL 自然过期 + FileExplorer 刷新已重拉目录树,无独立缺口) - [x] ✅ **P1-g** store.tasks.filter 污染 — **2026-08-09 核验+补全销账**:ProjectDetail 独立 taskApi.list 已修;ChatInput @项目 enrichment 独立拉取(projectTasksCache)已修 + @任务联想本批改独立全量缓存 taskSuggestionCache(隔离 Tasks 页筛选子集)+ mentionTotal 对齐 -**P2(打磨)**:幽灵 `--df-primary` / git 状态色 token / 控件统一(原问题 8 延伸)/ 死代码清理(PlanProgress/isLastUser) +**P2(打磨)**:✅ 幽灵 `--df-primary` 已清(2026-08-15:4 处引用迁 `--df-accent` 逐主题等价,双主题定义删除,零残留)/ ✅ 死代码 PlanProgress·isLastUser 已核不存在 / git 状态色 token / 控件统一(原问题 8 延伸) **批次 I(原 12 大改 · 后续专项)**:Dashboard 统计卡压底行(问题 1,依赖 P1 数据源)/ Projects 视图模式(问题 2)/ TaskDetail(4)·IdeaDetail(5)·KnowledgeDetail(6)·ProjectDetail(10)重设计 / project_event_repo 埋点接入(问题 3) diff --git a/src/components/ai/ConflictResolver.vue b/src/components/ai/ConflictResolver.vue index b5f237f..6fd9c10 100644 --- a/src/components/ai/ConflictResolver.vue +++ b/src/components/ai/ConflictResolver.vue @@ -123,7 +123,7 @@ watch( } .conflict-file--toggle:hover .conflict-filepath, .conflict-file--toggle:hover .conflict-toggle-text { - color: var(--df-primary); + color: var(--df-accent); } .conflict-arrow { display: inline-block; @@ -159,7 +159,7 @@ watch( border-radius: 4px; overflow: hidden; } -.diff-panel--a { border-left: 3px solid var(--df-primary); } +.diff-panel--a { border-left: 3px solid var(--df-accent); } .diff-panel--b { border-left: 3px solid var(--df-success); } .diff-panel-label { font-size: 11px; diff --git a/src/components/ai/ConversationSidebar.vue b/src/components/ai/ConversationSidebar.vue index aadba71..2ec5ae6 100644 --- a/src/components/ai/ConversationSidebar.vue +++ b/src/components/ai/ConversationSidebar.vue @@ -652,7 +652,7 @@ body.ai-sidebar-resizing * { width: 100%; height: 18px; padding: 0 4px; - border: 1px solid var(--df-primary, #4f8cff); + border: 1px solid var(--df-accent); border-radius: var(--df-radius-sm); background: var(--df-bg, #fff); outline: none; @@ -668,7 +668,7 @@ body.ai-sidebar-resizing * { width: 6px; height: 6px; border-radius: 50%; - background: var(--df-primary, #4f8cff); + background: var(--df-accent); flex-shrink: 0; animation: ai-conv-gen-pulse 1.4s ease-in-out infinite; } diff --git a/src/composables/ai/useAiContext.ts b/src/composables/ai/useAiContext.ts index 3702931..9716c32 100644 --- a/src/composables/ai/useAiContext.ts +++ b/src/composables/ai/useAiContext.ts @@ -27,7 +27,8 @@ import { setContextCallbacks } from './useAiEvents' // 模块级单例 ref,多窗口共享(分离窗口与主窗口共用同一 isCompressing)。 // 已知限制:分离窗口压缩时,主窗口的压缩按钮也显示 loading(反之亦然);非功能 bug, -// 但若需 per-window 独立压缩态需改为 inject/provide 或独立 store 实例,本版暂不处理。 +// 后端压缩本身 per-conv 幂等,共享态仅影响按钮 loading 展示; +// 若需 per-window 独立压缩态需改为事件同步/inject-provide,改造成本大,暂不处理。 const isCompressing = ref(false) /** diff --git a/src/composables/ai/useStreamRenderer.ts b/src/composables/ai/useStreamRenderer.ts index 929bbb9..54cbcff 100644 --- a/src/composables/ai/useStreamRenderer.ts +++ b/src/composables/ai/useStreamRenderer.ts @@ -139,7 +139,8 @@ export function useStreamRenderer(opts: UseStreamRendererOptions) { } /// 流式渲染:增量切块 + 块级 memo(前块缓存/末块重 parse) - /// 返回 { html, key } 数组:key 用 block 文本 hash(已完成块稳定/末块递增), + /// 返回 { html, key } 数组:已完成块 key 用 block 文本 hash(DOM 稳定), + /// 末块 key 恒为 'tail-1'(内容更新靠 v-html 响应式重设,不依赖 key 变化), /// 模板 v-for + v-html 分块渲染,已完成块 DOM 不重建 → 选文字保持。 /// /// AC-EFF-S1-1 增量:追加场景复用上一帧已完成块,只对「旧末块+增长段」增量 lexer, @@ -179,7 +180,7 @@ export function useStreamRenderer(opts: UseStreamRendererOptions) { _prevStreamText = text const n = blocks.length - let tailSeq = 0 // 末块递增序号,确保末块 key 每次不同触发更新 + let tailSeq = 0 // 末块 key 序号:每帧函数内重置且仅一个末块,key 恒为 'tail-1' return blocks.map((b, i) => { const isTail = i === n - 1 // AR-1 代码块降级:末块若是未闭合的代码围栏(```/~~~ 数为奇数,说明代码块还没结束), @@ -193,7 +194,7 @@ export function useStreamRenderer(opts: UseStreamRendererOptions) { const html = (degrade || longSingleBlock) ? escapeFallback(b) : isTail ? parseBlockNoCache(b) : parseBlock(b) - // 已完成块用文本做 key(DOM 稳定不重建);末块用递增序号(每帧更新) + // 已完成块用文本做 key(DOM 稳定不重建);末块 key 恒为 'tail-1'(v-html 每帧重设内容) const key = isTail ? `tail-${++tailSeq}` : `b-${simpleHash(b)}` return { html, key } }) diff --git a/src/styles/global.css b/src/styles/global.css index 1085d49..f3e47c5 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -24,8 +24,6 @@ --df-accent-hover: #6a5de0; --df-accent-soft: rgba(123,111,240,0.15); --df-accent-bg: rgba(123,111,240,0.08); - /* — Primary: 品牌主色(历史遗留 token,等价 accent,5 处引用:ConversationSidebar/PlanProgress/ConflictResolver/AdvancedSection 的 border/focus/活跃/link 态)— */ - --df-primary: #7b6ff0; /* — Semantic — */ /* 青绿:成功/流程 */ @@ -85,7 +83,6 @@ --df-accent-hover: #5b4bd6; --df-accent-soft: rgba(108,92,231,0.15); --df-accent-bg: rgba(108,92,231,0.06); - --df-primary: #6c5ce7; --df-success: #00b894; --df-success-bg: rgba(0,184,148,0.10);