Skip to content

Releases: Athosoo/dsh-git-graph-sidebar

v1.13.1

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 14:44

1.13.1 —— 插件不再自己合并规范

上一版把合并交给模型,但机械并集仍作为「草稿」留在插件里。这一版把它整条删掉:插件自己没有任何路径能合成一份规范。

删掉的东西

  • conventionsConsolidate、conventionsUnionSection、conventionsMergedBody
  • /git/conventions/consolidate 路由(现在返回 404)、git_conventions 的 draft 动作与 write 参数
  • GitApi.conventionsConsolidate、客户端合并计划面板、11 个 locale 键

留下的路径

  • read:把工作区、仓库、父仓库与散文文档(AGENTS.md 等)的完整正文交给模型(上限 20000 字符)
  • check:逐字段、逐规则报告差异,并在没有机械冲突但存在多份文档时提醒查重
  • write:落盘模型自己写的合并稿 —— 时间戳备份、被并入的仓库文档改成指针、指针下保留原文

面板的「Merge with AI」把一份写好的请求复制到剪贴板(客户端插件无法直接发起模型回合),插件自己一个字都不写。

测试

  • 旧的合并路径改为断言不存在:/git/conventions/consolidate 404、报告不写盘、面板永不出现
  • host 232/232、8 组 preview 断言全过、180 个 locale 键全部解析

安装后必须重启 DSH:宿主侧与客户端侧都改了。

资产文件名不带版本号(dsh-git-graph-sidebar.tgz),市场条目的 latest/download 自动跟随这个 Release。

v1.13.0

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 14:09

合并现在真的由智能体来做

1.10.0 的合并是确定性的并集:它只能合并正则看得见的东西,读不出两段话在说同一件事,也读不出「每节都写待定」的脚手架没有信息量。1.13.0 把合并搬到模型侧,代码只留真正机械的部分。

新增 read 与 write

  • action: read 交出每份文档的完整正文(工作区总纲、仓库自己的、祖先仓库的,以及 AGENTS.md / CLAUDE.md / .cursorrules / CONTRIBUTING.md),带来源、字节数、是否指针、是否截断;
  • action: write 落盘模型自己写好的合并稿:空正文拒绝、目标已存在且无 force 拒绝、旧目标先复制成 .bak-<时间戳>、被并的仓库文档改成指针(下面保留合并前原文,clone 下来照样能读);
  • 旧的 consolidate 退为 draft(机械并集草稿),check 不变。

提示词:谁来做判断

有冲突时不再让人去调机械合并,而是要求完整读文档、逐段比较、先给方案、用户同意后才写;并且写明「工具不可用就用你自己的文件工具」(agentTool 默认关闭)。文档之间没有机械冲突但存在多份时,也会提示一句「正文仍可能重复」——查重成了常驻指令,合并完成后自动消失。

面板:交接而不是执行

「AI 合并」和冲突条上的「查看并合并」会把一段现成的请求复制到剪贴板(客户端插件无法直接发起模型回合),粘贴到对话里发送即可。机械并集仍然一键可达——通知里的「先看机械并集草稿」,同样先预览再写。

接口与测试

  • 工具参数:action(required)+ body / write / force / absorb
  • host 252/252,客户端 preview 8 组断言全过;locale 189 键

这次 host 与客户端都改了,装完必须重启 DSH。

v1.12.1

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 13:51

主区域视图落地后现场发现的两处问题,1.12.1 修掉。

提交卡片不再压在输入框上

主区域里 .viewArea 是跟着内容长高的,所以整列按画布高度撑开,卡片被推到滚动区底部,正好被粘在底部的输入框盖住。现在整列高度按宿主自己发布的两个变量算:

height: calc(var(--dsh-conversation-viewport-height, 100vh) - var(--dsh-composer-height, 96px))

页面不再滚动,卡片也不可能被盖住;草稿变高导致输入框变高时,变量会跟着更新。

顺带把卡片挪到图谱右侧(主区域是横的):选中提交时左右分栏(右侧 320px、自己做滚动),没选中时不占位。侧边栏仍是原先的底部卡片。

被并入的仓库文档保留原文

整合会把仓库级 GIT_CONVENTIONS.md 改成指针。如果这个文件被 git 跟踪,那等于提交了一个指向本机工作区的死链接。现在指针三行之后会保留合并前原文,并带一行注释说明它是合并前副本;内部所有读取路径仍然先过指针标记,所以规则不会被重复计入。

自检

  • build-lib spliced 2843 / 3223 / 2153 / 449、patch-host already present 25
  • validate-lib 187 locale keys
  • test-host 243/243(新增「指针保留合并前原文」)
  • preview-tab 全过,新增一段主区域布局断言(高度含两个变量、左右分栏、卡片离开底部)

装完请重启 DSH:客户端的布局与视图注册都在启动时读取。

v1.12.0

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 13:24

1.12.0 — 图谱也能开进对话主区域

主区域视图(可选、可关闭)

  • 注册 conversation.view:id: "git-graph"(自造 id,不占内置视图那一格)、order: 70、label 用 thunk 随语言切换
  • 规范条上的「在主区域打开」开关打开它,视图右上角 × 关掉它,偏好记在 localStorage["dsh-git-graph:main-view"]
  • 默认关闭:没打开之前不注册任何东西,别人的视图页签条不受影响;侧边栏 tab 仍是主入口
  • 视图本体就是原来的 tab,没有 tab 描述符,choose() 已加守卫

文档

  • README.md / README.zh.md 开头重写为 Why this one / 为什么选它:规范进的是模型提示、规范会被读回(含 AGENTS.md 这类散文)、两份规范打架不会被悄悄投票、三个入口一套本体、全程本地只读
  • DEVELOPMENT.md 记下偏好键、注册代码、tab 守卫、字面量 t() 的坑与测试限制
  • HANDOVER.md 补 §7.13

接口与测试

  • locale 键 185 → 187;tab 源码 3189 行
  • preview-tab.mjs 的假 ctx 补 slots / sessions / 内存版 localStorage,新增断言组:偏好关不注册、开则注册进 conversation.view、× 关掉后 dispose 且偏好变 "0"、再开能重注册
  • test-host 242/242、validate-lib 187 键、patch-host already present 25、build-lib spliced 3189 / 2149 / 449

安装

宿主与客户端都改了,装完必须重启 DSH(Ctrl+R 不够),否则新面板与新视图都不会出现。

v1.11.0

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 12:21

这一版做了什么

规范不只写在 GIT_CONVENTIONS.md 里。很多工作区的提交规则写在 AGENTS.md、CLAUDE.md、.cursorrules 或 CONTRIBUTING.md 里,之前的版本完全看不见它们。

1.11.0 把这类散文文档也读进来(只读,永不改写):

  • conventionsSources() 在工作区根和仓库根各扫一遍 AGENTS.md / CLAUDE.md / .cursorrules / CONTRIBUTING.md,作为 foreign 来源单独返回,不混进「治理这批提交的规范文档」计数。
  • 它们和规范文档用同一个规则解析器(parseConventionRules():标题长度、type 词表、小写、句号、祈使句),所以散文里的「Keep the subject under 50 characters.」这种句子照样能被读出规则——不需要调用模型,判定是确定性的。
  • conventionsConflicts() 把它们的规则纳入比对与并集:谁的更严就按谁算(长度取最小、type 取并集、布尔「任一方要求即生效」),并新增 foreign 一项列出「文档里没有、或与并集不同」的规则,计入冲突数。
  • 每一步注入给助手的提示会写明:AGENTS.md also states … - it is not rewritten by a merge, so ask the user whether those rules should move into the document first。模型因此会先问,而不是默默按旧规范写。
  • 一键整合允许「只有一份规范 + 旁边有 AGENTS.md」时执行;计划里新增 leftInPlace——这些文件只读不写,因为工作区里别的工具在读它们。
  • 规范面板的合并计划会列出「保留原地」的文件(data-gitgraph-left)。

接口

路由 / 工具 变化
/git/conventions/conflicts 返回值新增 foreign: [{origin, docPath, keys}]
/git/conventions/consolidate 计划新增 leftInPlace: string[]
git_conventions 工具 同上一并返回

验证

  • test-host 242/242(新增第 [20] 段 10 项:散文文档被报成 foreign、把并集收紧到 50 字符、提示里出现 AGENTS.md、计划列 leftInPlace、合并后只读文件原文未变、count 0)。
  • preview-tab 12 段全过(新增 data-gitgraph-left 断言)。
  • validate-lib 185 个 locale 键全部解析;build-lib spliced 2843 / 3079 / 2149 / 449 行;patch-host 25 处幂等。

这次 host 与客户端都改了:装完必须重启 DSH,Ctrl+R 不够。

v1.10.1

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 10:14

补丁版。1.10.0 把规范能力做齐了,但冲突条只在真有冲突时才出现,想主动把几份规范整理成一份时,面板上没有入口。

规范面板自己带一个「合并规范」按钮

规范面板的标题行(Git 规范 / 文档名 / 状态 / 打开 / 更换框架 那一行)现在还有一枚 合并规范 按钮:

  • 文档存在才出现,操作进行中禁用;
  • 点了走的是和冲突条完全相同的流程:先出并集计划(哪些文档会被并掉、新增哪几节、合并后的规则并集),再点「写入并备份」才落盘;
  • 所以不管冲突条在不在,都能手动整理一遍。

只有一份规范时,不再当错误

只有一份规范在生效时,主机返回 convention-single-source。原来它会被当成错误红字显示,现在改成一句提示「只有一份规范,无需合并。」并清掉计划面板。

接口与测试

  • 行为不变的部分一律没动:/git/conventions/consolidate 不带 write 仍只出计划,git_conventions 工具仍是 opt-in;
  • locale 键 181 → 183(sidebar.consolidateOpen、sidebar.consolidateSingle);
  • preview-tab 的 tier-4 补一段:面板按钮出计划但不写盘、取消后计划面板消失;
  • 全链路自检:spliced 3068 / 2102 / 449、patch-host already present 25、183 locale keys、host 232/232、预览 12 段全过。

这次只动了客户端(lib/client.js)与文案,没有 host 变更;但插件是按包整体加载的,装完还是重启一下 DSH 最稳妥。

v1.10.0

Choose a tag to compare

@Athosoo Athosoo released this 27 Oct 05:47

AI 署名政策、排他性检测与一键整合。

AI 署名是明确的政策

前置字段新增 ai: required | optional | forbidden,默认 optional,老文档不受影响。required 要求每条提交信息带一个 AI 署名 trailer(Assisted-by: / Generated-by: / Co-authored-by: 都认),forbidden 只拦 AI 专用 trailer——人类结对提交的 Co-authored-by: 不算违规。检查读的是提交正文:commitCompliance() 的 git log 格式从 %H%x00%s 改成 %H%x00%s%x00%b%x1e,以前只读标题,所以根本看不到 trailer。和其它规则一样:面板始终标出,只有 strict: true 时才真的拒绝提交。

冲突会被报出来,不会被悄悄投票

conventionsConflicts() 把「管同一批提交」的文档三方对比——工作区 <工作区>/.dsh/GIT_CONVENTIONS.md、当前仓库自己的、以及祖先仓库的:字段(status / framework / strict / language / ai)与规则(标题长度、type 词表、小写、句号、祈使句)都比,但只有双方都明确写了同一个字段且取值不同才算冲突,沉默不算。有冲突时,每一步注入给助手的提示里都会带上这份分歧清单,并明确要求「不要自己选边,先问用户」——所以中途才加入工作区的插件、模型也不会闷头照旧规范写。

一键整合到工作区文档

「查看并合并」先把并集方案预览出来(新增几节、改写几节、哪些文档会被并掉),按「写入并备份」才落盘,落到 <工作区>/.dsh/GIT_CONVENTIONS.md。并集语义:长度取最严、type 取词表并集、布尔规则「任一方要求即生效」,各文档正文小节都会搬过来(同名标注来源)。每一份被替换的文件都留一份 .bak-<年月日-时分秒>,仓库级文档改成指针文件(inherited from …)——想退回随时能退。

助手自己也能查

打开 agentTool 后会注册 git_conventions 工具(action: check 列冲突、action: consolidate 出合并计划),不带 write: true 时只出计划不动盘。

接口与测试

新增 /git/conventions/conflicts、/git/conventions/consolidate,ai 透传到写入、预览、设置、工作区四条既有路由;locale 键 166 → 181。test-host 232/232(新增 [17] AI 署名、[18] 冲突与合并、[19] 工具三段),preview-tab 增加 tier-4 一段(AI 三态开关、冲突条、先预览后写入)。

这次 host 与客户端都动了,装完必须重启 DSH。

1.9.2 - 标签终于真的能和分支分开

Choose a tag to compare

@Athosoo Athosoo released this 25 Oct 09:53

1.9.2 — 标签终于真的能和分支分开

1.9.1 说「标签退出筛选排」,但只改了面板;主机那一行没动,所以装在插件里看不出任何变化。

修的是什么

lib/index.js:616 的 parseDecoration() 一直在做 .replace(/^tag: /, ""),把标签和分支都变成光秃秃的名字。客户端再聪明也分不出来——你截图里那 9 枚 v1.5.0 … v1.9.0 被当成「分支」画成实心青蓝,就是这个原因。

现在只剥 HEAD -> (和裸 HEAD),tag: 前缀保留,面板据此区分:分支是实心药丸、标签是灰色描边、当前分支额外加底色。

为什么 1.9.1 的测试没抓出来

scripts/preview-tab.mjs 的 fixture 是手写的,里面本来就写着 "tag: v1.0.0"——客户端逻辑在假数据上完全正确,而真实主机在链路的前一步就把前缀剥掉了。测试测的是自己的想象力。

test-host 因此新增第 [16] 段:真建仓库、真打 annotated tag、再断言 /git/graph 返回的 refs 里既有 tag: v1.0.0 也有无前缀的 main。现在 189/189。

验证

  • build-lib spliced 2843 / 1560 / 449 行
  • patch-host 23 处、validate-lib 166 个 locale 键
  • test-host 189/189、preview-tab 10 节全过
  • 安装后需 ==重启 DSH==(这次改的是主机半边,Ctrl+R 不够)

v1.9.1 - 标签不再占筛选项 / tags are not filters

Choose a tag to compare

@Athosoo Athosoo released this 25 Oct 09:43

1.9.1 — 标签不再占筛选项

一个标签只指向一个提交,静音它只能藏掉一行——它不该和分支一起排队。这一版把标签从筛选排里拿走,仍然留在提交行上作徽章。

变更

  • 标签退出筛选排:refGroups 不再收 tag: …,顺序变成「当前分支 → 其他本地分支 → 只有远程的分支」。host lib/index.js:616 不再剥掉 tag: 前缀,客户端据此区分标签与分支(1.9.0 里发布标签被当成分支画成实心 chip,就是这条前缀被剥掉导致的)。
  • 标签仍是行内标记:新增 refLabelOf,把 tag: v1.0.0 映射成 v1.0.0,行内徽章与导出的 SVG 都用它。
  • 可筛分支少于四条时整排不显示(SIDEBAR_TAB_FILTER_REFS_MIN = 4);已经静音过东西时仍然显示,因为「清除筛选」在那里。
  • 可见性过滤:标签不参与静音,但只被标签指着的提交必须仍算起点,否则静音任意分支时老版本提交会消失。
  • 清掉 1.6.1 遗留的死键 sidebar.expandGraph(「全屏查看」/「Full-window view」)。

验证

build-lib spliced 2843 / 1560 / 449 行、patch-host 23 处、166 个 locale 键、test-host 186/186、preview-tab 全过(含新的 refs 一节与「单分支时整排隐藏」用例)。

1.9.1 — tags are not filter candidates

A tag points at a single commit, so muting one hides exactly one row; it never deserved a slot next to the branches. Tags still show up on the commit rows as badges.

  • refGroups skips tag: …; host lib/index.js:616 keeps the prefix now so the client can tell a tag from a branch.
  • refLabelOf renders tag: v1.0.0 as v1.0.0 in row badges and in the exported SVG.
  • Fewer than four filterable branches and the row is not drawn at all (unless something is muted, because Clear filters lives there).
  • Dead sidebar.expandGraph keys from 1.6.1 removed.

v1.9.0 — ref chips: one per branch

Choose a tag to compare

@Athosoo Athosoo released this 25 Oct 09:15

1.9.0 — 引用标签:一个分支一枚

筛选那一排以前是「一个 ref 一枚标签」:main、origin/main、origin/HEAD、feat/x、origin/feat/x、tag: v1.8.2 各占一枚,同一个分支出现两次,符号引用也混在里面;超过十二枚的部分被直接切掉,看不见也点不到。

现在:

  • 一个分支一枚标签 — feat/x 与 origin/feat/x 共用一枚,静音一次两边一起关掉;标签的 title 把两个名字都写出来。
  • 符号引用不再出现 — HEAD、HEAD -> main、origin/HEAD 不成为标签。
  • 排序有意义 — 当前分支在最前,然后是其他本地分支、只有远程的分支,最后是标签(灰色)。同级按名字。
  • 不再被切掉 — 默认显示前十二枚,多出来的给 +N,点开变「收起」。
  • 一键清空 — 有任何一枚静音时,旁边出现「清除筛选」。
  • 行内徽章同步 — HEAD -> main 现在显示成 main,计数从 +4 变成 +2;导出的 SVG 用的是同一套标签。

Toolbar layout, zoom, export, search and everything else are unchanged.

Verification

  • scripts/test-host.mjs: 186/186 checks passed
  • scripts/preview-tab.mjs: export, search, ref chips, conventions, tier-3 and overview sections all green
  • scripts/validate-lib.mjs: 166 locale keys resolve, all fork identifiers defined

English

The filter row used to carry one chip per ref — main, origin/main, origin/HEAD, feat/x, origin/feat/x, tag: v1.8.2 — so one branch showed up twice, symbolic refs got their own chips, and anything past twelve was sliced off and unreachable.

Now it is one chip per branch: a local branch and its remote twin share a chip and mute together (the chip's tooltip names both), HEAD / HEAD -> … / origin/HEAD never become chips, tags keep a grey one of their own, the order is current branch → other local → remote-only → tags, the row folds to +N past twelve, and a Clear filters chip appears whenever something is muted. Row badges and the exported SVG use the same labels, so HEAD -> main reads as main.