Agent Timeline v0.6.0
本轮由有人值守的实机复测驱动:此前标
逐项点过,查出一簇长期静默失效的缺陷——根因是同一个 null。
新增(双端)
- 快淡入、慢淡出:面板变亮仍是
opacity.transitionMs(180ms)+ ease-out,指针一进来
立刻可读;变暗改走新 tokenopacity.transitionOutMs(500ms)+ ease-in,从容化开,
不再"看到一半就唰地消失"。
曲线必须随方向换,不能只拉长时长:ease-out 会把约 87% 的变化挤在前段,500ms 下观感
反而变成"唰一下再慢慢爬"。ease-in 先稳住、后段化开,才是想要的。
双端同一套语义(winOpacityAnimator、macFloatingPanel.updateTrackingAndOpacity)。
修复(Windows)
-
ItemsRepeater不给条目设DataContext——一个null打掉了整簇交互(本轮根因)。
ItemsRepeater不像ListView/ItemsControl会用ContentPresenter包一层,realize
出来的元素DataContext始终为null。模板里的x:Bind编译成直接绑定、不走
DataContext,所以画面完全正常——但每个DataContext is NodeViewModel vm的代码后
处理器都拿到 null 并静默 return。受害面:整条点击展开、chevron 展开、hover 高亮与复制
按钮、条目右键菜单。代号 chip 不受影响,因为它在ItemsControl里——这个反差正是佐证。
修法:NodeRepeater.ElementPrepared里补上 DataContext,所有处理器一起复活。
定位靠日志探针:CHEVRON sender=Button dc=<null>;修复后用 UIA 调用 chevron 自验,
画面差异从 0.91%(没反应)变为 34.65%(真的展开了)。 -
头部拖动:按住拖不走,点一下松开窗口反而黏着鼠标跑。原实现借系统原生移动循环
(ReleaseCapture+WM_NCLBUTTONDOWN/HTCAPTION),这在 WinUI 3 下不可靠——指针输入
走 XAML island 的 input site 而非顶层 HWND,模态循环常在按键已松开之后才启动,于是它在
等一个早就发生过的WM_LBUTTONUP。改为手动拖拽:捕获指针 + 按屏幕坐标位移调
AppWindow.Move,松开或捕获丢失即结束(后者不处理会一直粘在拖动态)。位移取屏幕坐标
而非元素内坐标,跨不同 DPI 的显示器才不漂;拖完即存位置。 -
整条点击展开在绝大部分面积上失效(实机值守发现)。
Tapped原先挂在一层夹在中间的
透明命中层上,而命令/派生纸面块是不透明 Border、可命中且自身没有 Tapped 处理器——
点在它们身上时事件只会往上冒泡到条目 root(root 当时也没有 Tapped),那层兄弟命中层
永远轮不到。可点区域只剩元信息行与块间窄缝。改为把Tapped挂到条目 root(对齐 mac
NodeViews.swift的.contentShape(Rectangle()).onTapGesture)并删掉命中层。 -
要点摘要行划不动:折叠态下派生区最显眼的那行,是全条唯一漏了
IsTextSelectionEnabled的文本。补上。 -
agent 回复区域右键出不来菜单:
IsTextSelectionEnabled="True"的 TextBlock 会
吞掉右键手势,使其到不了挂在条目 root 的Entry_RightTapped。命令区因为有 ❯ 列、
Border 内边距、右侧留白等大片非文本像素,右键落在那儿仍能冒泡上去——所以症状表现为
「只有自己发出的命令范围内有菜单」。修法:给条目内各文本加元素级RightTapped。
三处均经有人值守实机确认修复。
⚠ 注:这三处与上面的 DataContext 是两层问题叠在一起——命中层/属性/事件的修法本身
必要,但只修它们时仍然全无反应,直到 DataContext 补上才真正生效。 -
单实例保护:补上 Windows 侧缺失的入口闸——这是一处双端分叉,mac
App/main.swift一直有(发现有同 bundle id 的进程就exit(0)),Windows 侧从无对应物。
面板IsShownInSwitchers=false、无任务栏按钮、收进托盘后完全隐身,托盘图标在 Win11
默认还在溢出区——用户想确认它在不在跑,最自然的动作就是再双击一次 exe,所以这不是
边缘情况而是常规误操作路径。
两个实例并存的实际代价:摘要引擎各自挑同一批summary_pending节点跑 CLI(配额与
耗时双倍、summary_attempts提前耗尽);「replay 与 watcher 不并发写 codenames 表」
与AppSettings.Save的锁都只是进程内保证,跨进程失效;两个托盘图标导致「退出」
只关掉一个。(SQLite 本身自愈:WAL + busy 重试 +UNIQUE(agent, session_id, ts, command_hash)去重 +file_offsetsUPSERT,故 mac 注释里那句「silently lose writes」
在 Windows 这套姿态下并不完全成立,已如实记在代码注释。)
实现:windows/AgentTimeline/Program.cs取代 XAML 生成的 Main(csproj 定义
DISABLE_XAML_GENERATED_MAIN),Main 除首行外与生成版逐字一致,与 mac 同一位置——
在任何应用对象存在之前退出。闸的粒度是一个数据库(名字取AppPaths.DatabaseFile
的哈希):不同用户各有自己的%LOCALAPPDATA%故互不阻塞,同一用户的两个会话
(RDP + 控制台)共用一份 store 故被拦下——固定名的Global\会误伤前者,Local\
拦不住后者。实机验证:第二个进程 83ms 退出(ExitCode 0,赶在 XAML/托盘初始化之前)、
托盘只剩一个图标、强杀后可重启无残留 mutex 死锁、连开三次只剩一个。
验证(Windows)
- provider 档全链路打通(此前长期挂在「已知未验证事项」里,只验过失败降级链路)。
新增windows/scripts/provider-check/:本机 OpenAI 兼容 mock(真 HTTP、真协议)+ 端到端
编排。五项判定全绿——baseUrl 不带/v1时自动补全、Bearer 头带上、temperature=0、
解析choices[0].message.content→SummaryJson.Parse、落库summary_source='Provider'
且标题被 LLM 值替换。数据安全同 §3b:备份 → 文件级交换 → try/finally 还原 → 计数 + md5
双重核验。mock 不记录 prompt 正文(只留长度与 SHA256),Authorization 头日志脱敏。
仍未验:某个具体厂商端点的响应怪癖(需真凭据,不经手脚本)。