Commit Graph
8 Commits
Author SHA1 Message Date
Menghuan1918 76b57508f4 fix(ui): compact context menus + viewport-clamped submenu flip
减重:全部右键菜单(FileTree 行菜单 / TabBar tab 菜单 / GitLens 文件与
历史菜单 / FreeWindow 标题菜单)与「+」菜单切到宿主 Menu 原语的 compact
密度(26px 行高 / 12px 字 / 164px 卡片),图标随槽位 16→14,「打开方式」
子菜单图钉 20→16,还原工具型右键菜单的趁手感。

越界:宿主子菜单纯 CSS 定位(从父行向上、向右生长)不受视口钳制——树顶
部右键时「打开方式 ▸」子菜单伸出视口上沿,窄面板(280–400px)时伸出右
沿。新增 menu-flip.ts:菜单打开期间在 <body> 发布 data-dsh-sidebar-submenu
="down|left" 方向 token(y < vh/2 → down;x + 400 > vw → left),layout.css
据此翻转子菜单生长方向与 ::before 悬停桥;属性存续期即作用域,宿主自有
菜单不受影响。刻意不做 max-height 滚动钳制——overflow 裁剪会切断悬停桥。

测试:menu-flip.spec.tsx(token 纯函数 + hook 生命周期 + CSS 契约跨文件
一致性);tab-bar / file-tree 两个 spec 追加翻转向量断言;mount.e2e 追加
compact 行高(≤30px)布局级证据。设计偏差记录同步至
docs/plans/2026-08-22-open-with-menu-design.md。
2026-09-04 20:28:35 +08:00
Menghuan1918 1ec1565b13 refactor(client): 四处轮询站点迁移到 use-polling,语义逐一保持
- SubagentView useSubagentLive:self-scheduling(上一请求 settle 后才排
  下一次,不重叠)+ 每代 AbortSignal + signal.aborted 拦迟到写入,行为
  与原 disposed 标志等价(teardown 同步置 disposed 并 abort)。
- SideChatView:立即拉取 effect 与 2s 定时拆分——输入变化(含 running
  翻转)仍先拉一次转录,运行中间隔 tick 拉转录+徽章;fetchThread 自带
  的逐次 abort 与卸载 abort 原样保留。
- GitLens:可见时 2s 固定静默 tick,无初始突发(mount/scope 变更的完整
  刷新在别处);refresh 身份变化照旧重启间隔相位。
- ChangesTab:输入变化即拉一次(含隐藏态翻转),可见时 2.5s 固定间隔;
  pull 内部 pollGen 代际守卫不动。

守护 spec 全绿:subagent-live-polling + subagent-jobs-view 13/13、
sidechat-view + sidechat-transcript 29/29、git-view-worktree +
changes-tab + changes-ops 13/13;断言零改动。
2026-09-03 20:35:59 +08:00
Menghuan1918 5a1e75e46b fix(lint): 清零存量 lint 告警并接入 CI / Makefile 门禁
存量清理(首跑 141 errors / 21 warnings → 0 / 0):
- 删除孤儿 disable:SideChatView / Sidebar / selection-popup 三处 exhaustive-deps 豁免与 chunk-artifact 的 no-new-func 豁免(多行理由注释把 disable-next-line 顶离了实报行;selection-popup 改为提取 popupOpen 标志真修复)
- 死代码:未用导入(Sidebar×7、TextEditor、SideCardSection、config、fs-operations 及 6 个 spec)、sidechat-core 死累加器 total、chunk-loader.spec 死助手 registry、sidechat-seed-validation 死助手 toolResultMessage
- 真实小修:agent-opens 三处 throw 补 cause;lazy-chunk any → ComponentType<P>(P extends object);service.ts claimed 初值改定值赋值;chunk-loader task / spec 内 etag / pendingLoad / snapshot 改 const;terminal-links 去掉字符类内多余转义;SubagentView catalogs 空兜底 useMemo 稳定标识;editor-host.spec 组件提出大写 FakeViewer(rules-of-hooks);pty-helpers.spec 内联 require 提升为静态导入;panel-host-css 注释里的零宽空格改为可见写法
- 依赖数组豁免(均带理由):granular scope 字段(EditorHost / PdfView / ChangesTab / GitLens×2)、job.status 粒度(SubagentView×2)、清理期读 ref、mount-only 注册等;ctx(挂载期恒定)直接入 deps(Sidebar×3)、TextEditor previewScroll 补 scope(幂等)
- 刻意控制字符正则(conversation-draft / markdown-images)与宿主槽位 any 签名(context-types)以带理由豁免保留

接入:
- Makefile:lint 目标(typecheck 旁),check 聚合补 lint 保持「对齐 CI」语义
- ci.yml ci / ci-windows 两 job 与 release.yml 在 Typecheck 后加 Lint 步骤(release 注释同步顺序)
2026-09-03 20:00:08 +08:00
Menghuan1918 4002f3cc5c refactor(client): 统一 GitLens 错误归一化与 SubagentView 日志分级
- GitLens.tsx:六处 catch 里的 reason instanceof Error ?
  reason.message : String(reason)(refreshTarget/refresh/loadMoreLog/
  commit/checkout/runConfirmed)收敛为模块级 errorMessage(),
  两处模板字符串插值场景(historyLoadError/checkoutError 前缀)
  同样复用;归一化表达式与输出文本逐字不变。
- SubagentView.tsx:openSubagent/open session 失败的 console.warn
  改为 console.error,与同严重度失败路径对齐(Sidebar.tsx tab
  badge、TerminalView.tsx xterm open、service.ts urlTarget/plugin
  callback 均为 console.error);前缀与消息文本不变。tests/ 无任何
  钉 console.warn 的断言,已核实。
2026-09-03 12:05:48 +08:00
Menghuan1918 b7af498427 perf: stabilize renders (transcript row reuse, tree Sets, shared + options, batched drags)
SideChat transcript: every 2s poll rebuilt ALL row objects, so every
row (markdown parse + DOMPurify included) re-rendered even when the
log had not changed. transcriptRows now takes the previous poll's
rows and re-adopts the position-aligned rows whose content is
identical (reuseRows) — only the changed tail rebuilds. The view
feeds the memoized array back through a ref; unit tests pin the
identity contract (unchanged rows keep object identity, changed rows
and everything past the change rebuild, tool-result landings never
re-adopt).

FileTree: expanded/revealed membership was an includes() scan per
rendered row (O(rows × expanded) per render on deep trees); one Set
per render keeps it O(1) per row.

Shell: buildNewTabOptions was inlined in the two Workbench JSX
sites — two fresh arrays per render (drag state, resizes) re-rendered
every LeafView's + affordance. One shared memo now.

DiffPane resize / TerminalView ResizeObserver: pointer and resize
streams fired a setState / glyph-measuring fit() per event; both ride
per-frame batching now (frame-batcher in the core, a local rAF gate
in the lazy terminal chunk). SessionLens sizes each row's content
with a Blob (a UTF-8 encode of the whole edit) — that moved from
per-row-per-render into one memoized pass per changed fold.
2026-09-01 16:01:34 +08:00
Menghuan1918 427552e4f9 perf: cut the boot and poll overhead (one settings fetch, one git process per tick, one fold per poll)
Boot: loadPrefs and loadExternalDisable each fetched the settings
document, serially, before the first paint — and the second had no
timeout, so a stalled wire kept the sidebar unmounted forever. Both
decisions now ride ONE fetch (loadBootDecision) under the existing
2s race.

GitLens: the 2s silent poll re-listed worktrees on every tick (a
second git process per tick for a list that almost never changes, and
a fresh worktrees array re-render each time). Silent ticks now fetch
only the selected checkout's status; every 15th tick (~30s) re-lists
and re-runs auto-selection, so an agent-created linked checkout is
still picked up mid-session.

ChangesTab: extractFileOps parses every accumulated tool/call (up to
4000 events); the poll ran it once for the badge and the render ran
it AGAIN per tick, and the fresh array defeated the downstream memo.
The fold now runs once per poll and its result rides a ref shared by
badge and render (reset on session switch).
2026-09-01 15:58:44 +08:00
Menghuan1918 f024fbf092 fix(changes): 会话事件改走宿主 changes.ops 路由 + diff 展开二级设置 + 视觉迭代
CI 修复(plugin-mount 的 ctx.sessions.get TypeError ×1003):
- 客户端 runtime 无事件日志面——badge/SessionLens 原在客户端直读
  ctx.sessions.get(id).events / ctx.on('session/event'),全部不可达。
- 新增宿主路由 changes.ops:live 会话日志优先,冷会话回放
  sessionPersistence.inspect;afterSeq 增量(缺省游标含 seq 0,
  显式游标为 seq > afterSeq,同 sidechat.events 约定),窗口上限
  4000 与客户端累加器一致。
- ChangesTab 轮询(mount 一拉 + visible 2.5s 增量)折入 ops,写
  模块级 opCounts 缓存供 badge 同步读取;SessionLens 改纯展示。

diff 展开二级设置(changesDiffFloat,默认浮窗):
- prefs 四处接线 + git tab settings select(浮窗/面板,图标选项卡)
- 预览面板「展开为 diff tab」按设置落点:浮窗居中弹出或源 pane
  下方 split;i18n 全 21 词典同步。

视觉迭代(真机挂载截图审查后调整):
- Session 视角:kind 徽章为左轨,大小+相对时间右对齐元列;失败
  操作行红色内嵌条;文件组头降为三级标签并加组间距。
- Git 视角:untracked '?' 徽章与新增同绿色;stage 按钮改 plus 图标。
- diff 折叠行:可展开折叠带 › 箭头 + 次级对比度,静态 gap 不再
  显示 pointer/hover;预览头路径改尾部截断(RTL 技巧,保文件名)。

验证:typecheck ✓ / vitest 1123 ✓ / pnpm test:mount(钉 alpha.2 CLI)
14/14 ✓;真机挂载截图(badge=5、双视角、浮窗展开)0 console error。
2026-08-31 17:52:59 +08:00
Menghuan1918 24a3813c63 feat!: 合并 Git 面板与文件追踪为统一「文件变动」tab(双视角 + 统一 diff 栈)
在 PR #471(file-trace)基础上的演进:

- 合并 tab:git tab(id 保留,兼容持久化布局)升级为「文件变动」双视角
  tab——Git 视角(原 GitView 全部能力:staged/unstaged/提交/历史/worktree·
  子仓库选择/右键菜单/确认弹窗)+ 本轮文件视角(原 file-trace:会话事件
  日志实时折叠的模型读写编辑记录,按文件分组、新增类型筛选 chips、相对
  时间);file-trace tab 移除(未随任何版本发布)。
- 统一 diff 组件:新 src/client/diff/ 模块(rows.ts 引擎 + DiffRows/
  DiffFiles 渲染器 + highlight.ts 语法着色)——git diff 与会话操作 diff
  共用一套渲染:mod 改写配对(del-run/add-run 对半标蓝)、行内字符级
  高亮(修复了旧实现旧侧失配不高亮的问题,改为行对象身份键)、上下文
  hunk 折叠、git hunk 间未输出区间按行号范围生成不可展开折叠、语法着色
  色相落位 diff 三色空档、+n −m 统计 chips、行底色 tint;DiffTab 改用
  该栈(git diff tab 从此也有高亮)。
- 交互:两视角共用底部可拖拽预览面板(点击文件/提交/操作即预览,不再
  直接开 diff tab;面板可刷新、可键盘/拖拽调高、git 目标可一键展开为
  独立 diff tab);视角选择与面板高度持久化在 tab.meta;git 行 XY 徽章
  按状态字母着色;选中行高亮。
- i18n:fileTrace* 十键重命名为 changes* 前缀,git 键值更新为「文件
  变动」,新增 7 键(视角/筛选/面板操作),全部 21 个词典同步。
- 结构:src/client/changes/(ChangesTab/GitLens/SessionLens/DiffPane/
  ops)+ src/client/diff/;GitView/DiffView/filetrace/ 删除;git 样式
  从 sidebar.module.css 迁至 changes.module.css。
- 测试:builtins 8→7(git tab 承接 badge pin)、diff-rows(unified
  转换/mod 配对/间隙折叠/统计)、changes-tab(壳交互 jsdom)、
  diff-files-collapse(原 DiffView 折叠行为钉住)、changes-ops(原
  filetrace 数据层)、git-view-worktree 迁移至 GitLens;全量 1122 通过。
- 文档:README ×2 功能矩阵合并、external-plugin-guide §4.4 与内置清单
  7 tab、mount e2e 菜单标题同步。
2026-08-31 01:31:22 +08:00