# 更新日志 本仓库的版本历史。英文摘要附在每个条目末尾。 ## v2.2.0 — 2026-09-07 **诊断层第 1 项:分析区新增「结果与证据」块——不信 Agent 自述,用日志证据回答「做成没有、凭什么说做成」。** - **六格 + 综合**:任务完成(最后一轮 `turn/end` 的原因不是 error/aborted/interrupted/blocked,且最后一步是回答;max-tokens 算结束但写明原因)、测试 / 构建 / Lint(对 bash 命令做**命令位置**正则识别——`cat vitest.config.ts`、`grep pytest`、heredoc 正文都不算;初版覆盖 JS/TS、Python、Rust、Go、Swift 与 make/ctest/docker build,npm/pnpm/yarn 的 `check` 脚本按测试计;一条命令命中多类分别记;通过 = 该调用没有错误标志且返回**末行**没有非零退出码;每个类别以最后一次运行的结果为准,此前别的命令最后一次失败的条数小字注明——「同一条命令」按命中的那段命令算(去掉 `cd` 前缀、重定向、`&& echo PASS` 装饰),不按整行 bash,真实日志里同一个测试脚本换着写法跑了十几次;`command -v pytest`、`pytest --version` 这类探测不算跑;后台任务(结果只有 `started background job bash-N`)按之后 `job_output` 末行的退出码计,取不到就不计并标注;点格定位到最后一次运行所在的那一步并打开该步详情)、产物(写入/编辑/补丁类调用成功触及的文件去重,格内展开路径列表)、人工确认(最终回答之后有没有真人消息,只给有无、不解读内容)。综合:任务没正常结束或某类验证最后一次失败 → 「部分成功」;一条验证命令都没有 → 中性灰的「未验证」并写明本场没跑测试/构建/Lint;其余「已完成」。中英双语、明暗主题同步。 - **退出码口径(真实日志核对)**:dsh 的 bash 工具只在非零退出时把 `[exit code: N]` 追加在末行,后台任务 `job_output` 的末行是 `[status: completed, exit code: N]`;退出码只认末行——正文里引用别的日志的 "exit code: 1"(实测案例:docker 构建输出被 `head` 出来,末行是 `[status=Failed]`)不算本次命令失败。退出码在压空白/截断**之前**从原文读出并随工具对象携带(新字段 `exit`),5000 字面板全文上限不变。 - **两条链路同口径**:上传链路解析时记录每轮收尾原因(`turnEnds`)与真人消息时刻(`userMsgs`,只认 `source.kind = user`,指令文件/插件注入/子代理回报不算);实时链路从时间线的 `turn/end` 读原因,窗口里没有时退回 turn-error / turn-max-tokens / turn-tail 节点各自的说法,真人消息取 `user` / `steering` 节点;payload 只多几个小字段,并进重绘签名。 - **诚实边界**:code 模式会话(`run_code`)里脚本内部派发的真实命令暂不识别(解析层没展开 `tool/code-dispatch*`),块里如实标注;项目自定义的测试包装脚本(`deploy/x.sh test_y.py`)、循环变量里的测试文件(`for t in …; do sh $t`)、被 `| tail` / `|| true` 掩盖的退出码都识别不到,会显示「没有跑」或「通过」。 - 纯逻辑在 `verdict.js`(`detectValidationKinds` / `exitCodeOf` / `validationPassed` / `artifactPaths` / `outcomeEvidence`,规则常量在 `ANALYSIS_RULES`),新增 38 个单元测试(main 基线 63 → 101:含测试先失败后通过 / 只构建没测试 / 没有任何验证 / 一条命令命中多类 / 非零退出码、后台任务关联 job_output、探测命令排除、引号参数不碰撞、类别以最后一次运行为准,以及实时链路原料契约与节点退回),全部通过。 _EN: Diagnosis layer, item 1 — the analysis section gains an **Outcome & evidence** block that answers "did it get done, and what proves it" from log evidence instead of the agent's own claims. Six cells: task (the last `turn/end` is not error/aborted/interrupted/blocked and the last step is an answer; max-tokens counts as ended with the reason shown), tests / build / lint (command-position regexes over bash commands — `cat vitest.config.ts`, `grep pytest` and heredoc bodies do not count; JS/TS, Python, Rust, Go, Swift plus make/ctest/docker build in this first cut, with an npm/pnpm/yarn `check` script counted as tests; one command can count for several kinds; passed = no error flag and no non-zero exit code on the output's last line; each category is judged by its last run with earlier last-run failures noted, where "the same command" is the matched segment with `cd` prefixes, redirections and `&& echo PASS` decorations stripped — real logs run one test script a dozen ways; probes like `command -v pytest` or `pytest --version` do not count; a background job counts by the exit code on its later `job_output` last line and is left out and noted when none arrives; click a cell to locate the step of the last run), artifacts (files touched by successful write/edit/patch calls, deduplicated), human check (whether a human message followed the final answer — never interpreted). Overall badge: an abnormal ending or a last-run failure → "partial"; no verification command at all → a neutral "unverified"; otherwise "completed". Exit codes are read from the untouched last line before whitespace collapsing and truncation and carried as a new `exit` field (verified on real logs: dsh appends `[exit code: N]` only on non-zero exits; an "exit code: 1" quoted mid-output is not this command's failure). Both render paths carry the same raw material — turn endings and human message times — with the live path reading `turn/end` off the timeline and falling back to turn-error / turn-max-tokens / turn-tail nodes. Honest limits: code-mode sessions (`run_code`) are flagged as not recognized; project-specific test wrappers, loop variables and `| tail` / `|| true` masking are invisible. 38 new unit tests (63 on main → 101), all green._ ## v2.1.0 — 2026-09-04 **新增设置页开关:可隐藏侧边栏入口([#11](https://github.com/lamost423/dsh-maze/issues/11))。** - **需求来源**:只用「实时迷宫」页签的用户用不上侧边栏底部的常驻入口(窄栏模式下占一个独立图标位),此前只能本地改包删掉那段注册。 - **实现**:设置面板新增「Maze」一节(`settings.section` 槽位,生态先例 better-sidebar 同款),内含「侧边栏入口」开关,默认开、不改任何人的现有习惯。关闭即时生效——`slots.inject` 的幂等销毁器当场摘除注册,无需刷新;重开同理。「实时迷宫」页签与已打开的迷宫页不受开关影响。 - **持久化**:存 localStorage(`dsh-maze:v1:settings`),按浏览器保存;同一浏览器的多个标签页之间实时同步(监听 `storage` 事件)。没走宿主设置文档(`ctx.settingsScope`)是权衡不是做不到:那条通道要求插件的宿主半边注册设置命名空间(我们的宿主半边刻意留空),且在非本机访问的页面上会失效;一个界面开关不值得为此长出宿主半边,better-sidebar 也是同样的取舍。存储被禁/损坏时按默认值运行,开关在页面存续期内仍可用;存储里的未知键写回时原样保留,老版本不会抹掉新版本的偏好。 - **兼容**:`@deepseek-ai/dsh-client-ui-settings` 仅作类型依赖(可选 peer),产物 require 零新增;宿主没有设置壳时该节静默不渲染,默认行为不变。 - 实机验收于全新 `@deepseek-ai/dsh@0.1.2-rc.1` 宿主:加载零报错、开关双向即时生效、刷新后状态保持、两个标签页互相同步不用刷新。经独立代码评审加固后测试 63 个全绿(新增 14 个覆盖设置存取:默认值/损坏或异型 JSON/存储抛错/订阅通知与异常隔离/跨标签同步/未知键保留)。 _EN: Adds a settings toggle to hide the sidebar entry ([#11](https://github.com/lamost423/dsh-maze/issues/11)). Live-tab-only users never needed the persistent footer button (a full icon slot in rail mode) and previously had to patch the installed package locally. The settings panel now carries a "Maze" section (the `settings.section` slot, same seat better-sidebar uses) with a "Sidebar entry" switch — default on, so nobody's habits change. Flipping it takes effect immediately in both directions via the slot registration's idempotent disposer, no reload; the Live Maze tab and an open maze page are unaffected. The preference persists per browser in localStorage (`dsh-maze:v1:settings`) and syncs live across that browser's tabs via the `storage` event. Skipping the Host settings document (`ctx.settingsScope`) is a tradeoff, not an impossibility: that channel needs the plugin's Host half to register a settings namespace (ours is a deliberate no-op) and goes inert on non-loopback pages — one UI switch is not worth growing a Host half for, and better-sidebar made the same call. Blocked or corrupted storage falls back to defaults with the switch still working for the page's lifetime; unknown keys in storage survive writes, so an older build never erases a newer one's preferences. `@deepseek-ai/dsh-client-ui-settings` is a type-only optional peer, so the bundle's requires are unchanged, and on hosts without the settings shell the section silently never renders. Accepted live on a fresh `@deepseek-ai/dsh@0.1.2-rc.1` host: clean load, immediate two-way flips, state surviving reload, two tabs syncing without reload. Hardened after an independent code review; 63 tests green (14 new covering the settings facade: defaults, corrupted or odd-shaped JSON, throwing storage, subscription with error isolation, cross-tab sync, unknown-key preservation)._ ## v2.0.0 — 2026-09-03 **2.x 转正:`latest` 从 1.1.0 切到 2.0.0,修复新宿主上插件加载失败([#10](https://github.com/lamost423/dsh-maze/issues/10))。** - **为什么现在转正**:npm `latest`(1.1.0)的产物 require 已被宿主 `0.1.2` 移出模块表的 `@deepseek-ai/dsh-client-runtime`,在 DSH Desktop 2.0.4(内核 `0.1.2-alpha.1`)上迷宫入口直接抛错——普通用户按文档默认安装装到的就是坏的(#10)。上游宿主 `@deepseek-ai/dsh@0.1.2-rc.1` 与拆分出的客户端包本周发到了 npm(`next` 标签),2.x 第一次可以对着正式发布的宿主构建发版([#7](https://github.com/lamost423/dsh-maze/issues/7) 一直在等的前提)。 - **构建基座换轨**:devDependencies 从自建宿主软链换成 npm 的 `0.1.2-rc.1` 包组;补齐源码 type-import 到但此前没声明的包(api-session-controller、ui-chat、ui-renderer、ui-trajectory、ui-session、session、store)。 - **适配 rc.1 类型**:`sessionId` / `useProjection` / `useSessions` 这些槽位标准 props 的声明合并在 rc.1 里归 `dsh-client-ui-session`,装进 devDependencies 后即解;`Context.sessions` 存在两份声明合并(客户端 `ISessions`,以及经 `dsh-workspace/types` 间接拖进来的服务端 `SessionStore`),TS 绑了服务端那份,在唯一使用点显式断言客户端面。 - **兼容代价**:还在老宿主(npm `latest`,`0.1.0-rc.6` ~ `0.1.1-rc.2`)上的用户,装插件时手动钉 `dsh plugin add dsh-maze@1.1.0`;README 安装表已随之翻面。 - 功能与 `2.0.0-alpha.2` 一致。typecheck + 49 测试 + 构建全绿;产物 require 审计:只剩 `dsh-client-store` / `dsh-client-ui-primitives` / `react`,旧包名零残留。 _EN: Promotes the 2.x line: `latest` moves from 1.1.0 to 2.0.0, fixing the plugin failing to load on new hosts ([#10](https://github.com/lamost423/dsh-maze/issues/10)). The 1.1.0 bundle requires `@deepseek-ai/dsh-client-runtime`, which host `0.1.2` removed from its module table, so on DSH Desktop 2.0.4 (kernel `0.1.2-alpha.1`) the maze entry threw on load — and the documented default install handed exactly that to ordinary users. With host `@deepseek-ai/dsh@0.1.2-rc.1` and its split-out client packages now on npm (tag `next` — the precondition [#7](https://github.com/lamost423/dsh-maze/issues/7) was waiting for), 2.x can finally build and release against a published host. The build base switches from self-built host symlinks to the npm `0.1.2-rc.1` package set, declaring every package the source actually type-imports. Two rc.1 type adaptations: the slot standard props (`sessionId` / `useProjection` / `useSessions`) are declaration-merged by `dsh-client-ui-session`, now a devDependency; and `Context.sessions` carries two competing merges (client `ISessions` vs the server `SessionStore` dragged in via `dsh-workspace/types`), so the single use site asserts the client face. Users still on older hosts (`0.1.0-rc.6` ~ `0.1.1-rc.2`) pin `dsh-maze@1.1.0`. Functionally identical to `2.0.0-alpha.2`; typecheck + 49 tests + build green, and the bundle require audit shows only `dsh-client-store` / `dsh-client-ui-primitives` / `react` — zero traces of the old package name._ ## v2.0.0-alpha.2 — 2026-08-29 **修 alpha.1 实机验收查出的一处数字打架:实时视图头部的 Token 总数少算。** - **现象**:同一画面上,头部指标条写「Token in 3 · out 23」,泳道标签写「output 25 tok」,宿主自己的底栏写「Input 6 · Output 25」。头部那个是错的。 - **根因**:宿主 `0.1.2` 里只发工具调用的 assistant 步不产生 assistant 节点,它那次请求的 token 落不到任何一行迷宫上,只存在于轮级账里。上一版把泳道统计改成取轮级账,但页面头部仍然自己按行累加,于是漏掉了那一步。写代码的会话里纯工具调用的步骤占比很高,会话越长漏得越多。 - **改法**:轮级账同时取出未命中缓存的输入(宿主 `TurnTokenUsage.uncachedInputTokens`,按其契约覆盖该轮每一次计费尝试),连同输出一起进泳道统计;页面头部优先用泳道统计里已经算对的值,没有时才回退按行累加。上传链路的日志每步都带 usage,走回退路径,行为不变。 - 新增一条契约测试:一步只发工具调用、不产生 assistant 节点时,泳道总数必须等于轮级账而不是行累加。49 个测试全绿。 _EN: Fixes one number disagreeing with itself, caught while accepting alpha.1 on a real host. The live view's header read "Token in 3 · out 23" while the lane label right beside it read "output 25 tok" and the host's own footer said "Input 6 · Output 25" — the header was wrong. Under host `0.1.2` an assistant step that only calls tools produces no assistant node, so that request's tokens land on no maze row and exist only in the turn account. The previous release moved lane stats onto the turn account but left the page header summing rows, so it dropped those steps — and coding sessions are full of them. The turn account now also carries uncached input (`TurnTokenUsage.uncachedInputTokens`, which by contract covers every billed attempt in the turn), and the header prefers the lane totals, falling back to row sums only when there are none (the upload path, whose logs carry per-step usage, is unchanged). A contract test pins it: with a tool-only step carrying no assistant node, lane totals must equal the turn account, not the row sum. 49 tests green._ ## v2.0.0-alpha.1 — 2026-08-29 **适配宿主 `0.1.2` 的客户端拆包与新会话模型。这一版只给自己从上游 master 构建宿主的人,发在 `next` 标签上;从 npm 装宿主的用户请继续用 `latest`(`1.1.x`),升上来反而会打挂。** - **包迁移**:宿主删掉了 `@deepseek-ai/dsh-client-runtime`,`defineStore` / `EngineStoreHandle` 迁到新的 `@deepseek-ai/dsh-client-store`;`ClientContext` 回到 cordis 的 `Context`,`ISessions` / `SessionFace` 归 `dsh-api-session-controller`,`SessionId` 归 `dsh-session`。`package.json` 的 `dsh.client.inject` 与 `tsdown` 的 external 同步换名——旧名字留在那里会让宿主的模块表查不到而直接抛错,这正是 [#7](https://github.com/lamost423/dsh-maze/issues/7) 的现象。 - **实时迷宫按新节点模型重写**:`0.1.2` 把 Conversation 拆成 target 中立的快照,节点不再挂在会话快照上、聊天内容归 ui-chat 的 chat target。有序节点改从 `order` + `nodes.get(key)` 走,工具调用与结果合成一个已结算节点,进行中的步改读 `assistant-step` 的 `running` 状态,轮次锚点改用 timeline 的 turn 起点(原来靠数用户消息推断,事件窗口从半途打开时会错)。 - **按实测修扫描**:在真宿主上冒烟发现步数和工具数会读丢(日志里 2 个步骤 1 次工具调用,界面只显示「1 steps · 0 calls」)。原因是只发工具调用的 assistant 步根本不产生 assistant-step 节点,该步由独立的 tool-call 节点代表。扫描改为按 location 的 (turn, step) 归组,谁先到谁建行。 - **turn 级精确 token**:完成的一轮在 turn-tail 上带宿主的精确账,覆盖该轮每一次计费尝试,包括失败后被重试的那些——这些 token 没有任何 assistant 节点承载,按步累加永远看不见。已完成的轮用轮级账,仍在跑的轮回退到步累加。 - **子会话花名册改为不导航**:上一版调 `sessions.openSubagent()` 打开子会话,实测那是个导航动作,会把用户正在看的会话直接切走。现在改成纯被动观察,只订阅子会话的 Conversation 绑定。代价是在本视图挂载前就已结束的子会话读不到历史——宿主公开契约里没有「不导航地加载子会话历史」这条路。 - **peer 依赖标为可选**:拆分出来的新包还没发到 npm,照常规写法声明会让 pnpm 自动去装 peer 而撞上 404,谁都装不上。宿主提供的包本来就不该从 registry 装,标成可选是如实的写法。 - 测试 48 个全绿(新增按新节点模型对齐的 fixture、以及「绝不导航」「按内容而非 openState 放行」两条契约测试)。 _EN: Adapts to host `0.1.2`, which re-split the client packages and swapped the conversation model. This build is for people who build the host from upstream master themselves — it ships on the `next` tag, while npm-host users stay on `latest` (`1.1.x`), where upgrading would break them. `dsh-client-runtime` is gone: `defineStore` / `EngineStoreHandle` move to `@deepseek-ai/dsh-client-store`, `ClientContext` returns to cordis `Context`, `ISessions` to `dsh-api-session-controller`, `SessionId` to `dsh-session` — with `dsh.client.inject` and the bundler externals renamed to match (a stale name misses the host module table and throws, which is [#7](https://github.com/lamost423/dsh-maze/issues/7)). The live maze is rewritten for the target-neutral snapshot: ordered nodes via `order` + `nodes.get(key)`, settled tool nodes instead of call/result pairing, in-flight steps from `assistant-step` status, turn anchors from the timeline. Smoke-testing on a real host caught steps and tool calls being dropped — an assistant step that only makes a tool call produces no assistant-step node at all, so scanning now groups by the location's (turn, step). Completed turns now report provider-exact tokens covering every billed attempt, including failed-and-retried requests no assistant node ever carried. The subagent roster no longer calls `openSubagent()`: that turned out to be a navigation action that switched the user's current session away — it is a passive observer now. Peer deps on the not-yet-published host packages are marked optional, otherwise pnpm auto-installs them and hits a 404. 48 tests green._ ## v1.1.0 — 2026-08-26 **观感大版本:空间收紧 + 轨道加高 + Token 脉冲双向 + 行内图例 + 柱形定版。** - **空间收紧**:无上方支路时泳道头到主干 82→58px、主干到轨道 44→36、轨道底垫减半、顶部起步 34→30;信箱留白收编——内容缩放后比容器矮时容器高度贴内容,迷宫框不再上下空一条。 - **轨道加高**:密度 18→40(新增独立标题行)、Token 56→92、上下文 70→100——省出的空转高度全部给数据区。 - **Token 脉冲双向 + 柱形定版**:基线之上未缓存输入(缓存命中作上半区半透明背景、自有刻度),基线之下推理+可见输出走独立刻度——输入动辄上万、输出常只有几百,同向堆叠时输出永远被压扁,上下分开后两边各自撑满。读数柱宽 = min(步长−缝, 10px) 钉步中点:密集会话自动呈细尖峰、稀疏会话保底存在感;时长语义由迷宫胶囊条承担,不重复编码。 - **行内图例 + 计数**:每条轨道标题行带彩点图例(密度轨道按类别计数、Token 轨道四层、上下文阈值标签),随双语与主题;`run_code`/`node` 归入命令类。 - **柱间留缝**:密度色条与 Token 柱步步可分(太窄时放弃留缝保可见),缓存背景保持连续当参照带。 - 全套演示素材(主视觉 / 六个功能 GIF / 社交预览图)按最终布局用真实会话重录。 _EN: A visual milestone. Tightened idle chrome (lane-header-to-main-path 82→58px with no up-detours, main-to-tracks 44→36, halved bottom padding, letterboxing removed — the canvas hugs its content when shorter than the container). Taller tracks (density 18→40 with its own caption row, token 56→92, context 70→100) — the reclaimed idle height goes to data. Token pulse goes bipolar: uncached input above the baseline (cache hits as a translucent upper-zone backdrop on its own scale), reasoning + visible output below on an independent scale — inputs run to tens of thousands while outputs are often a few hundred, so same-direction stacking always crushed the output. Bar width is now min(step span − gap, 10px), pinned at the step midpoint: dense sessions naturally render as thin spikes, sparse sessions keep presence; duration semantics stay with the maze capsules. Inline legends with per-category counts on every track caption; `run_code`/`node` classified as shell. Inter-bar gaps keep steps distinguishable (cache backdrop stays continuous as a reference band). Every demo asset re-recorded from real sessions on the final layout._ ## v1.0.0 — 2026-08-26 **`dsh-trace-compare` 更名 `dsh-maze`,1.0 里程碑。** - **为什么更名**:项目已从「对比工具」长成完整的执行观测台——迷宫、数据轨道、执行分析、多会话对比是四个并列的一等能力,「trace-compare」这个名字装不下了。迷宫是本项目从第一天起的招牌视觉语言,名字回到它身上。 - **改了什么**:npm 新包 `dsh-maze`(旧包冻结在 v0.7.0 并标记弃用、附迁移指引);GitHub 仓库改名 `lamost423/dsh-maze`(旧地址自动重定向,star/issue/历史全保留);dsh 内入口更名「执行迷宫 / Maze」;README 中英全部重写,全套演示素材换成真实 8.6 小时会话的新录屏。 - **功能与 v0.7.0 一致**:本版是更名与品牌重塑,无行为变更。 - 迁移:`dsh plugin --profile web remove dsh-trace-compare && dsh plugin --profile web add dsh-maze`。 _EN: `dsh-trace-compare` becomes `dsh-maze` for the 1.0 milestone. The project outgrew "compare": the maze, the data tracks, the execution analysis and multi-session comparison are four first-class capabilities now — and the maze has been this project's signature visual language since day one, so the name goes to it. New npm package `dsh-maze` (the old one is frozen at v0.7.0 and deprecated with a migration pointer); the GitHub repo is renamed with automatic redirects (stars/issues/history preserved); in-app entries become "Maze"; both READMEs rewritten and every demo asset re-recorded from a real 8.6-hour session. Feature-identical to v0.7.0 — this release is the rename and rebrand. Migration: remove `dsh-trace-compare`, add `dsh-maze`._ ## v0.7.0 — 2026-08-26 **分析层三件套(执行分析面板 / 泳道数据轨道 / Agent 关系图谱)+ 请求级失败可见化 + 对比扩到 5 个文件(同任务智能识别)。** - **执行分析区(主界面直出,迷宫下方)**:数据一到即渲染在迷宫下方的文档流里,整页纵向滚动、无需任何按钮——摘要三卡(工具失败与恢复 / 时间消耗 / 上下文压力)+ **耗时分布散点图**(每工具一行、sqrt 横轴铺开长尾、全局 P50/P95 参考线、失败点放大标红、悬停看单次调用)+ 工具结果矩阵(成功/失败/扑空/盲重试/成功率,附 P50/P95/最长耗时分位)+ 失败恢复链——每个失败调用之后发生了什么:原样重试 / 换参数 / 换工具 / 未恢复(分类看失败后的下一次调用;恢复 = 失败后任意工具在 120 秒内再次成功,超窗如实标注;链只统计失败 ✗——扑空 · 与盲重试 ↻ 计入矩阵各自列、不单独进链,盲重试也不算恢复证据);点一条缩放到该失败并打开详情面板。全部数字是对已判定数据的确定性聚合,不调 LLM,规则在 `verdict.js` 的 `analyzeFailureChains`/`ANALYSIS_RULES`。 - **泳道数据轨道(📊 轨道,可开关)**:泳道带底部三条与迷宫同一时间轴联动(缩放/平移/空闲折叠/播放全跟随)的轨道——**工具调用密度**(每次调用一根刻线,按读取/检索/命令/编辑/其他类别着色,宽 = 真实时长);**Token 脉冲**(每步堆叠柱:缓存输入/未缓存输入/推理/可见输出——用真实日志验证 `usage.inputTokens` 是未命中缓存口径、`cacheReadTokens` 是命中口径,上下文总量 = 两者之和);**上下文压力**(折线+面积,纵轴随数据自适应——按整窗满刻度画的话低占用会话的曲线全贴底边看不出变化;百分比与 70%/90% 阈值线按真实窗口换算、只在落进可视范围时画,压缩呈现为锯齿下落)。窗口表在 `verdict.js` 的 `CONTEXT_WINDOWS`(DeepSeek V4 = 1M 按官方口径收录);观测峰值超过表值时视为表已过时、自动退回绝对 token 显示——绝不显示超过 100% 的占用。日志没报 usage 就不画后两条轨道,不占高度。 - **Agent 关系图谱(分析区内的块)**:主 Agent 与子代理的星形总览——节点大小 = 该 Agent 消耗的 token(输入+缓存+输出,无真值时按调用数并注明),连线粗细 = 工具调用数,运行中的子代理虚线标示;点子代理节点跳到它在时间轴上的位置并打开详情。只在真有子代理数据时出现(依赖 v0.4.0 的子代理折入;stock dsh 无该能力时自然隐藏)。 - **密集会话可读性 + 头部指标条 + 热力进度条**:稀疏模式(当前窗口可见步数超阈值时自动启用——标签只留失败/回答/子代理/长步,支路弧线变细,≥4 条支路的密集段收「×N」聚合徽标、点击放大,放大后标签逐级补齐);轮次交替底色与轮次标签避让(多轮长会话不再叠字);播放进度条热力化(活动密度铺底 + 失败红刻线,拖到坎坷段即达);会话头部指标条(模型 · 总时长 · 步数/调用 · Token 输入/输出——**刻意不含缓存重读**,累计缓存会得出数亿级的吓人数字 · 峰值上下文);Token 脉冲改「缓存半透明背景(自有刻度)+ 增量三层柱」——97K 缓存不再把几百 token 的产出压成细边;上下文压缩事件「⌄−N%」标注(相邻样本掉 ≥20% 即标,悬停看压缩前后真值);耗时散点图每行加自身 P50/P95 刻度。 - 配套:实时链路每步新增 `inTok`/`cacheTok` 真值(子代理聚合节点同步汇总);界面双语与明暗主题全量覆盖新面板与轨道;分析聚合的纯逻辑(已结算调用过滤 / 活动时长合并 / 分位数 / 工具矩阵 / 请求级失败计数 / 同任务可比性)下沉 `verdict.js` 可测模块并有单元测试覆盖。 _EN: The analysis layer arrives as three pieces. **Execution analysis panel (📈)**: three summary cards (tool failures & recovery / time spent / context pressure), a per-tool result matrix (ok/failed/no-result/blind-retry/success rate with P50/P95/max durations), and failure recovery chains — what happened after each failed call: identical retry / changed args / switched tool / not recovered (recovered = any tool succeeds again within 120s; over-window reported honestly); click a row to zoom to that failure. All numbers are deterministic aggregations of judged data — no LLM. **Lane data tracks (📊, toggleable)**: three tracks under each lane band sharing the maze's time axis (zoom/pan/idle-folding/playback all linked) — tool-call density (colored by category), token pulse (stacked cached-input / uncached-input / reasoning / visible-output per step; verified on real logs that `usage.inputTokens` is the cache-miss share and `cacheReadTokens` the hit share), and context pressure (line+area; with a known model window it shows percentage plus 70%/90% thresholds, compaction appears as sawtooth drops). The window table lives in `verdict.js` `CONTEXT_WINDOWS` (DeepSeek V4 = 1M per the official release); when the observed peak exceeds the table value the table is treated as stale and the track falls back to absolute tokens — never a >100% reading. **Agent graph (🕸, a UI option)**: a star overview of the main agent and its subagents — node size = tokens consumed, edge width = tool-call count, running subagents dashed; click a node to jump to its span on the timeline. The button appears only when subagent data exists._ **请求级失败可见化 + 对比扩到 5 个文件(同任务智能识别)。** - **请求级失败画进迷宫**(实时 + 上传两条链路同口径):模型没吐出任何内容就失败的请求,此前在图上是纯空白——实测有会话前 2 分 40 秒全在失败重试,图上却像"什么都没发生"。现在 `llm/retry`(失败后安排重试)画成红色支路条,条长 = 退避等待窗口,图标 ↻、标签 ↻N,判定依据带失败原因 / 第几次重试 / 退避时长;`turn/end` 的 `error`(终局失败,无再重试)画成红色 ✗ 点标记。两类标记计入支路统计,退避窗口按活动时间参与空闲折叠判断(不再被折叠掩埋)。全程失败、一步未成的会话也照画。 - **对比扩到最多 5 个 session log**(原 1~2):五套泳道配色(明暗主题各一套),图例、泳道带、统计卡、文件上限、`?load1..load5` 直载全部跟进。 - **同任务智能识别**:按各文件首条用户消息是否一致判定「是不是同一个任务的多次跑」。同任务 → 对比件全量泛化到 N 泳道:轮次对齐线连成跨泳道链(双泳道保留原有差额标注,N 泳道标注各自本轮耗时)、手动锚点可钉任意两条泳道、支路盘点扩成 N 列(差额列仅双泳道显示);任务不同 → 仅同轴并排,对比件停用。识别结果在图例明示(⛓ 同一任务 ×N / ≠ 任务不同),不默默切换。 _EN: Request-level failures become visible (live + upload, one contract): a request that dies before producing any content used to render as pure blank — a real session spent its first 2m40s failing and retrying while the maze showed "nothing". `llm/retry` now draws as a red detour bar (length = backoff window, ↻ icon, rationale carries cause / attempt / delay); a `turn/end` error (terminal, no more retries) draws as a red ✗ point marker. Backoff windows count as activity for idle folding. Compare now takes up to 5 session logs (was 1–2) with five lane palettes in both themes. Same-task detection (identical first user message) gates the compare kit: same task generalizes it to N lanes (turn alignment as a cross-lane chain, anchors between any two lanes, N-column detour inventory with a delta column at 2 lanes); different tasks render side-by-side only — the verdict is shown in the legend, never silent._ ## v0.6.2 — 2026-08-25 **适配 DSH Desktop 桌面端**(issue #4,感谢 @devyujie 反馈)。 - **暗色主题切 tab 闪白**:iframe 层背景硬编码浅色、srcDoc 页面首帧按默认浅色变量绘制,暗色要等 onLoad 后 postMessage 才翻转——切 tab 重挂载 iframe 时闪一帧白。三层修掉:iframe / 面板底色跟随宿主暗色标记(`body[data-ds-dark-theme]`);srcDoc 挂载时预置 `data-theme="dark"` 让首帧即暗色;页面自初始化优先尊重预置属性(否则「宿主暗 + 系统浅」会在解析完成时翻回浅色)。 - **Trace 对比面板关闭按钮与窗口按钮重叠**:DSH Desktop(Electron)用 titleBarOverlay,原生「最小化 / 最大化 / 关闭」悬浮在页面右上角,正压在面板的 ✕ 上。✕ 的位置加 `env(titlebar-area-*)` 偏移——桌面端自动下移让出窗口按钮区,浏览器里这些变量不存在、走 0px 兜底位置不变。✕ 同时补上暗色配色(此前暗色下仍是白底)。 _EN: DSH Desktop adaptation (issue #4, thanks @devyujie). Dark-theme tab-switch white flash: the iframe layer's background was hardcoded light and the srcDoc page painted its first frame with default light variables (dark only arrived via postMessage after onLoad), so every iframe remount flashed white. Fixed at three layers — iframe/surface backgrounds follow the host's dark attribute, the srcDoc gets `data-theme="dark"` pre-injected at mount so the first frame is already dark, and the page's self-init respects the pre-injected attribute. Close-button overlap: DSH Desktop (Electron) uses titleBarOverlay, floating native window controls over the top-right corner right where the surface's ✕ sits; the ✕ now offsets by `env(titlebar-area-*)` (0px fallback keeps browsers unchanged) and gains proper dark-theme styling._ ## v0.6.1 — 2026-08-23 修一处悬停卡残留,并换上 v0.6.0 新界面录制的全套演示动图。 - **全量重建时收掉悬停卡**:钉锚点的第二次点击、缩放、过滤等都会触发迷宫全量重建,重建把悬停中的节点直接移出 DOM,`mouseleave` 永远不会到达——悬停卡就卡在画面上,直到下次悬停才被顶掉。重建前统一收起。 - 文档:README 换上新录的演示动图(对比:同一任务 Flash vs Pro;实时迷宫:真实会话页签内重播 + 跳回聊天;新增长会话可读性一节)。 _EN: Fixes a stuck tooltip — anchor-pinning, zooming, and filtering all trigger a full maze rebuild that removes the hovered node from the DOM, so `mouseleave` never fires and the hover card stayed on screen until the next hover. The rebuild now dismisses it. Docs: README ships freshly recorded demos on the v0.6.0 UI (compare: same task on Flash vs Pro; live maze: replay inside a real session tab with jump-back-to-chat; plus a new long-session legibility section)._ ## v0.6.0 — 2026-08-22 **UI 大改版:一次设计评审驱动的全面重做——看得清、拖入即读、去 AI 味配色。** - **画布自适应滚动**:整图 fit 在内容偏高时会把迷宫压到十几个百分点(双会话实测 0.24×,节点文字 2.6px 全糊)。缩放跌破可读下限改为按宽度铺满 + 纵向滚动,时间轴刻度钉在顶部不随内容滚走,首帧自动定位到主干线;滚动模式下普通滚轮归滚动、缩放走 ⌘/Ctrl+滚轮。实测双会话 0.24× → 0.79×。 - **拖入即读**:上传后直接呈现完整迷宫(原先节点条 opacity 0,非得先找到播放键才看得见自己的数据);播放降级为可选回放,按钮显示「重播」。 - **全新配色「钢蓝 + 赭褐」**:明确告别靛/紫系(AI 生成界面的招牌色)。两条对比泳道一冷一暖(红绿色盲可分),主干节点用泳道主色、绿色只留每轮最终回答(原先整条主干染绿与图例语义冲突);轮次对齐线降为中性灰,全图高彩度色从五个收敛到三个。 - **界面精致化**:设计令牌重构(明暗两套)、毛玻璃浮层(详情/盘点/悬停卡)、ghost 工具条(只有播放键实心)、页头并行化(1280 下页头 259→156px,迷宫多拿高度)、图例单行横滚、泳道标题显示上传文件名、全局字阶下调一档。 - **可达性与健壮性**:正文/刻度文字对比度提到 WCAG AA;折叠时间轴的刻度标签逐个避让不再互相叠字、轴标签精度随步长(14h 跨度不再连排六个「13h」);375px 视口横向溢出修复(774→375);触屏设备控件抬到 44px 触控下限。 - **实时泳道显示模型名**:`request/header` 不属于会话快照的 surface 事件,浏览器侧从来拿不到模型名。配套宿主 fork 注册 `modelIdentity` 会话投影(宿主侧折叠全量日志),本插件经标准投影钩子探测读取——stock dsh 无此键时自然降级,兼容不变。 _EN: Major UI overhaul from a design review. Canvas adaptively switches to width-fill + vertical scroll with a pinned axis when meet-fit drops below legibility (two-lane real case: 0.24× → 0.79×), first frame lands on the main path. Uploads render the full maze immediately (playback becomes optional replay). New "steel blue + ochre" palette retires the AI-signature indigo/purple: warm/cool lane pair (CVD-safe), lane-colored main-path nodes with green reserved for final answers, neutral turn-alignment lines. Refined chrome: glass overlays, ghost toolbar, parallelized header, single-line legend, filenames in lane titles. Contrast raised to WCAG AA, tick labels self-collide-avoid with step-aware precision, 375px overflow fixed, 44px touch targets. Live lane now shows the model name via a host-fork `modelIdentity` session projection with capability probing — stock dsh degrades gracefully._ ## v0.5.3 — 2026-08-21 **长会话布局修复:迷宫不再随会话时长挤成一条竖线。** - **支路槽位贪心复用**:支路泳道从「每条独占一层」改为按横向占位(出程弧、条形、回程弧、标签)贪心装箱——前一条支路画完的槽位可被后续支路复用,首选方向仍按序号上下交替保持原有观感。层数从「支路总数的一半」塌缩到「同一时段真正互相重叠的支路数」,画布高度基本与会话时长无关(4.2h/455 步/96 支路的实测会话:viewH 4159 → 1439)。 - **布局随缩放窗口重算**:装箱、布局、画布高度全部挪进 build() 按当前窗口重算——整图态挤在同一时段的支路,放大到单轮后自动重新摊开。 - 同槽相邻支路的下方标签复用原有的行内防重叠抑制,不互相叠字。 _EN: Long-session layout fix — detour lanes switch from one-slot-per-detour to greedy interval packing on each detour's horizontal footprint (out-arc, bar, back-arc, label), so slot count collapses to the true concurrent overlap and viewH stays flat regardless of session length (real 4.2h/455-step/96-detour session: viewH 4159 → 1439). Packing/layout/canvas height now recompute per build against the current zoom window, so detours crowded at full view re-spread when zoomed into a turn._ ## v0.5.2 — 2026-08-21 浮层加可见关闭按钮(右上角 ✕,带「关闭(Esc)」提示)。v0.5.0 起对比面板挂 `shell.overlay` 全屏盖住侧栏后,界面上没有任何可见出口,只能靠碰运气知道 Esc——实际用户第一次就被困住了。Esc 与切换会话自动关闭的行为保持不变。 _EN: The overlay surface gains a visible close button (top-right ✕, titled "Close (Esc)"). Since v0.5.0 the compare surface mounts on `shell.overlay`, covering the sidebar with no visible exit — first-time users got stuck unless they guessed Esc. Esc and close-on-session-switch behavior unchanged._ ## v0.5.1 — 2026-08-21 对比可读性三连修: - **加载自适应**:时间轴去掉 460 秒固定下限,短会话(如 72s/43s 双会话对比)不再被压扁在左侧、对齐标注挤成一团;Tmax 贴合内容跨度(×1.04 给右缘旗标留呼吸位)。 - **本轮耗时口径**:轮次对齐线从「会话开始算起的累计墙钟」改标「本轮耗时」(该轮最早节点 → 回答完成):轮与轮之间等用户输入的空闲不再计入,两次运行的速度对比不再被空闲污染。图例悬停注明口径。 - **推理量标签自解释**:无 usage 真值时从「N 段推理」改为「推理 N 段(日志未报 token 用量)」——中转站日志常缺 `reasoningTokens`,与原厂日志并排时单位不同,标签自带原因。 _EN: Three compare-readability fixes — the axis's 460s floor is retired (short sessions fit the viewport on load); turn-alignment labels switch to per-turn time (turn start → answer done, inter-turn user-input waits excluded); the reasoning-volume fallback without usage is self-explaining ("reasoning N chunks (no token usage in log)")._ ## v0.5.0 — 2026-08-20 **界面双语。** 整页 UI 中英双语:嵌入宿主时经 postMessage 实时跟随 dsh 的语言设置(同主题跟随的通道模式),独立打开按浏览器语言兜底。判定依据从成品文案改为语言无关的结构化键值 `{k, p}`,展示端按当前语言集中渲染——切语言即时生效,已加载的会话数据无需重新解析。仓库 README 调换为中文默认(英文在 README.en.md)。 _EN: The whole UI ships bilingual (zh/en), live-following the dsh host's language setting via postMessage (same channel pattern as theme following) with a browser-language fallback standalone. Verdict rationales become language-neutral structured `{k, p}` keys rendered in the current language — switching is instant, no re-parse. The repo README flips to Chinese-default with English in README.en.md._ ## v0.4.0 — 2026-08-20 **子代理执行折入实时迷宫。** - **新功能**:dsh 子代理会话(模型调 `subagent` 工具派生的任务)以聚合支路节点折入实时迷宫——挂靠在派生它的主干步上、与父会话共享时间轴;节点内的子条是子代理全部已判定的工具调用(参数 / 返回 / 判定齐全);运行中的子代理实时生长并标注"仍在运行";点击节点可跳回主对话中的派生位置。 - **身份与文案**:子代理节点在图上、支路段标、悬停预览卡、详情面板显示自己的标签("子代理 ×××")与"子代理支路"身份;派生关系写作"⤴ 由主干 SN 派生的子代理任务,完成后结果汇回主干",不再错误套用失败探索的"此路不通,折返"文案。 - **入图纪律**:仅 `origin: 'subagent'` 且非临时的子会话入图——手动"在新对话分支"与 side-chat 临时子会话不算子代理;已结束且活动完全早于可见窗口的陈旧子代理不画(与父会话窗口外步骤同一处理口径),运行中的照留。 - **兼容性**:子代理支路依赖宿主"后台打开子会话历史"的能力(`SessionFace.open`)。官方 `0.1.0-rc.6` – `rc.8` 尚无此能力,插件自动静默降级——不报错,其余全部功能不受影响;在具备该能力的宿主构建上即刻生效。 - **顺带修复**:内部步号(如 S100000)不再出现在任何用户可见位置。 _EN: Fold dsh subagent child sessions into the live maze as aggregated detour nodes — anchored at the spawning main-path step on the parent's clock, with the child's judged tool calls as sub-bars, live growth while running, and subagent-specific identity copy across labels, hover cards, and the detail panel. Only `origin: 'subagent'`, non-ephemeral children qualify; stale pre-window children are dropped. Requires the host's background history-open capability (`SessionFace.open`); absent through official rc.8, the feature degrades silently._ ## v0.3.3 — 2026-08-19 修复实时页签:新步骤开始(纯推理、零工具调用)时整张迷宫瞬间透明。根因是无保护取 `tools[0].name` 打断 build()。 _EN: Fix live-view blackout at the start of every tool-less in-flight step._ ## v0.3.2 — 2026-08-19 并行工具调用按调用分行(瀑布行),不再挤在一条杠上。 _EN: Parallel tool calls render as per-call waterfall rows._ ## v0.3.1 — 2026-08-19 主题跟随宿主明暗切换;紧凑页头。 _EN: Host theme following and a compact header._ ## v0.3.0 — 2026-08-19 对比语义升级:按轮次自动对齐两条会话、手动锚点、每轮支路盘点。 _EN: Turn-aligned compare semantics — alignment lines, manual anchors, per-turn detour inventory._ ## v0.2.3 — 2026-08-19 实时窗口诚实化(窗口外陈旧步计数展示而非乱画);判定防引用误报。 _EN: Honest live window and quote-proof failure signatures._ ## v0.2.2 — 2026-08-19 真实 token 计数(推理 / 输出)、搜索过滤工具栏、SVG / PNG 导出。 _EN: Real token counts, search/filter toolbar, SVG/PNG export._ ## v0.2.1 — 2026-08-19 判定 v2:共享 verdict 单真相源、长度阈值退役、行为学盲目重试簇检测。 _EN: Honest verdicts — shared verdict module, no length thresholds, behavioral blind-retry detection._ ## v0.2.0 — 2026-08-18 上传对比页 + 实时迷宫首个公开版本。 _EN: First public release — trace upload/compare page plus the live maze._