Skip to content

Releases

v0.1.7 — 窄轨头像不再糊 + VIS 五条全部自动化(含像素层)

Choose a tag to compare

@yefengliu1 yefengliu1 released this 16 Oct 10:36

窄轨里的像素小人是糊的(真 bug,由新增的视觉断言 + agent 看截图抓出)

窄轨模式(≤1000px 折叠侧栏,或用户手动收起)里,头像被压成 24×24,而 sprite 画布是 56×24 —— preserveAspectRatio="xMidYMid meet" 于是缩到 0.43×。非整数倍 → 像素格被抹平,3× 放大截图肉眼可辨。这正是本仓 VIS-03 自己写下的规矩:「像素头像在非整数倍尺寸下必然糊」。

修的过程踩到一条不明显的:只把外层 viewBox 换成 24 宽的裁切窗没用。<use> 引用 <symbol> 时会自建视口(默认取外层视口),symbol 又按自己的 56×24 meet 缩进 24×24 —— 于是又是 0.43×,而且小人贴在左边缘被切掉半边。

正确修法两条一起上:

  1. 每个 <use> 显式声明画布视口(width=56 height=24),symbol 永远按 1× 画;
  2. 窄轨开一扇 24 列的裁切窗(OX=16 起的身体)放进 24px 的框 = 1×。

连带的设计约束:裁切窗只有 24 列,而编排里有 ±8 格走位 —— 所以窄轨是静态徽章(状态由强调色圆环 + 待答红点表达),卡片舞台照旧跑全套编排。

两条都写进了 build_client.py 的构建期断言:谁删掉,窄轨就会重新糊。

VIS 五条不再是「人工上设备量」

它们要的都是可测量的事实,没有一条本质需要人眼:

eval 现在的判定
VIS-01 姓名可见/不截断 1280 与 1100 两个宽度断言;窄轨走 title
VIS-02 一屏放得下 grid.scrollHeight == clientHeight(实测溢出 0px)
VIS-03 只走 24 网格 断言「框 / viewBox 是整数倍」(卡片 2×、窄轨 1×)+ 每个 <use> 带画布视口
VIS-04 无空白格 + 运功有动效 getAnimations() 真有动画在跑
VIS-05 八席主色 与源码 SEATS 表逐字一致

新增像素层(真渲染出来的像素)

让浏览器把截图解码成 ImageData(Node 没有内置 PNG 解码器):

  • ✓ 选中卡左色条的像素就是强调色(want=#7FB4C4 got=rgb(127,180,196))
  • ✓ 选中卡姓名像素对比度 ≥4.5:1(实测 9.23:1) —— 「文字太暗」这类以后由它拦
  • ✓ 卡面不是纯色块(主题开着时,卡内亮度标准差 > 0,证明山水透得出来)

审美那一层不设人工闸门:产物 /tmp/dsh-agent-grid-shots/board.png(CI 作为 artifact 上传),由 agent 看截图给结论。本次判定:通过(选中态一眼可辨;层级 选中 > 待答 > 运功 > 休息 > 虚席;无滚动条)。

冒烟合计 33 项(跳过项都带原因打印)。evals.md §6 改判为 ✅ 可判定,新增 §6.1(像素层 + agent 审美判定)与 §6.2(这次 bug 的完整复盘)。

完整 diff:v0.1.6...v0.1.7

v0.1.6 — 选中态修复 + 待答假阳性修复(0.2.0-rc.2 两处 API 漂移)

Choose a tag to compare

@yefengliu1 yefengliu1 released this 16 Oct 08:25

一、选中态根本不存在("看不清当前主窗口是哪个 agent")

0.2.0-rc.2 的会话列表 store 形状是 { ids, byId, phase, projectionsBySession } —— 没有 current。老代码读 state.current / snapshot.current 全拿到 undefined,于是 is-active 一帧都不会亮;连带 reconcile 的 currentIsBlank、seatWorkspace 的兜底、claimPendingSeat 里 setSeatBinding(..., snapshot.current) 一起失效(最后那处会把 undefined 绑进席位)。

真值在官方 uiSession 服务上:current 是 binding source,getSnapshot().key 就是主窗口会话(publishMain() 按 retainedBy.mainView 选出来)。现在新增 currentSessionId 源 + 订阅,组件用 useCurrentSessionId(),四处引用统一改过来。

二、选中态与「待答」原来共用同一条视觉通道

两者都是「1px 边框 + 同色内描边」,而且 --dsx-accent 是每席自己的身份色(铁拐 #5A5F66 那种在暗色里几乎认不出来);叠上脉冲后,"在等你的普通席"反而比"当前席"更抢眼。现在拆成两条通道:

状态 通道
选中(当前主窗口那一席) 强调色左色条 + 强调色名字 + 强调色淡染底 —— 别人都不用这套
待答 / 待裁 朱砂边框 + 外圈呼吸,且只作用于非当前席;当前席同时在等你时,色条/边框保持强调色,等待只走外圈脉冲

窄轨(收起)模式同步换成强调色。

三、「当前钟离没有待回答的事项,为什么状态还是待答」

seat-activity 投影里 attention 的配对清除失效:resultOf() 还在按老形状找 block.type === 'tool-result' + block.toolCallId,而 rc.2 是

data.message.toolCallId = "call_…"          ← callId 在 message 上
data.message.content[]  = { type:'text', text }   ← 普通文本块

于是永远返回 undefined —— 回答拿不回来、attention 清不掉,卡片一直挂「待答」;顺带卡片那行「结果」也永远是空的。现在两种形状都认,非文本结果给占位。

stateVersion 3 → 4:作废旧投影缓存,历史会话按新解析重算(否则那条假「待答」会一直留在缓存里)。

完整 diff:v0.1.5...v0.1.6

v0.1.5 — 侧栏边距对称 12/12 + 卡面半透明

Choose a tag to compare

@yefengliu1 yefengliu1 released this 16 Oct 07:28

侧栏边距修正:左右内缩对称 12 / 12

宿主给侧栏内容区用了「左 −4 / 右 −12」的负 margin 把内容贴到侧栏边缘(.hHd-Xa_regionArea 的 margin:0 -12px 0 -4px),于是 .dsx-root 原来的 padding:2px 4px 8px 被放大成「左 16 / 右 4」—— 右边卡片几乎贴着侧栏边缘,这就是「侧栏边距不一致」。

改成左 0 / 右 12 后实测:卡片落在 12..268,左右各 12,与宿主自己的 Plugins 行(14..266)同一量级且对称。表头的 padding 也从 2px 收到 0,标题与计数跟卡片同一左右沿。

看板卡面半透明

卡面 background-color 用 color-mix(… 86%, transparent) 留 14% 透明:在「表面半透明、山水在后面」的主题(宋律)里,整块不透明的看板会把侧栏背景全挡掉 —— 这正是「侧栏看不到背景」的一半原因(另一半是主题没生效,已在 dsh-theme-songgrid 0.1.2 修掉)。

hover 改成用 background-image 叠一层染色,而不是把 background-color 整个换掉 —— 换掉的话卡面会在悬停瞬间变全透明,9-10px 的小字直接坐落在山水上。is-active / is-empty:hover 同步处理。

完整 diff:v0.1.4...v0.1.5

v0.1.4 — 适配 DSH 0.2.0-rc.2(含 0.1.1–0.1.3 回顾)

Choose a tag to compare

@yefengliu1 yefengliu1 released this 16 Oct 07:23

0.1.4 — 适配 DSH 0.2.0-rc.2

第三方客户端插件在 0.2.0-rc.2 上有四层静默失败,逐条修掉:

  • 兼容闸门:每个 @deepseek-ai/dsh* peer 范围必须满足运行版本,否则插件行被悄悄禁用(只在 stderr 留一行)—— ^0.1.5-rc.2 → ^0.2.0-rc.2。
  • 客户端半边注册:dsh-client-modules 用行的 specifier 匹配包自己的 name,不一致则永不注册(表现为宿主半边 Running、UI 上什么都没变)—— @local/dsh-agent-grid → dsh-agent-grid。
  • 构建产物:lib/client.js 把 id 硬编码在 __ModuleLoader__.load({id}) 里,改名后不重建会 duplicate factory registration —— 已用 build_client.py 重建。
  • 被移除的 API:ctx.settingsScope.bind({namespace}) → ctx.configForms.get(ns);sessions.open(id) → uiWorkspace.openSession(id)。

README / README.zh 新增「四种静默死法」移植笔记;evals.md 同步改名。

0.1.2 — 正在跑第一个 turn 的会话不再被当成空白槽端走

现象:从某席开始的任务,跑到一半被挪到别的格子上。根因是 blank 的语义是「folded prefix 里没有 turn」,所以刚开始跑第一个 turn 的会话仍然是 blank,平台的 connectWorkspace() 按「复用该工作区第一个 blank」把它端走了。

修法:两条新建路径先过闸门(ownedBlankIn() 探有主的待命槽 / createFreshSession() 自己造会话直绑本席),认领规则加 claimedByOther 闸 —— 任何情况下都不抢已有主的 blank。代价是同工作区会出现多个 blank 会话,但「席位持有的 blank ≤ 1」的约束不变。

0.1.1 — 切走不再丢待命席位

空白槽清理收紧;claim 改走工作区归属;clear 与换目录后不再跳到别的席位。


安装:dsh plugin --profile web add dsh-agent-grid(或 GitHub 源)
完整 diff:v0.1.0...v0.1.4

v0.1.0

Choose a tag to compare

@yefengliu1 yefengliu1 released this 22 Sep 17:49

First public release of 定员八席 · Eight Standing Seats — a fixed 2×4 board of standing agent seats for the DeepSeek Harness sidebar.

What's in it

  • Seat identity is permanent, sessions are disposable payload — adding, removing or reordering sessions never makes a cell change occupant
  • Three orthogonal states — persona / activity / context, deliberately not collapsed into one field
  • Seven labels — vacant, standing by, working, to review, resting, awaiting answer, awaiting approval
  • Per-seat process on the card — a host-side projection surfaces each seat's latest tool call, reasoning, tool result and answer
  • Main pane stays stock — only a seat badge is injected into the conversation header
  • Escape hatch — Settings → General → Sidebar switches back to the stock sidebar by unregistering, not hiding; survives refresh and host restart

Install

dsh plugin --profile web add dsh-agent-grid

Verified on DSH 0.1.5-rc.2. Not affiliated with DeepSeek.