Files
deepseek-harness/.agents/notes/implemented/architecture/2026-07-30-command-row-copy-contract.zh.md
T
creatixchu f4111a3701 fix(ui): drop the caption from the /permission error text too
Review round: the no-caption rule the Agent Note states applied only to the
success texts, leaving `permission · unknown permission preset "bogus" (…)`.
The error text now reads `unknown preset "bogus" (…)` and its exact wording
is pinned; the fixture mirror drops `JSON.stringify` for the host's own
quoting so the two cannot drift on a quoted argument.

The Note now states the line it draws: the rule bans a caption for the
command's own value, not the vocabulary, so `/plan`'s `Plan mode off.` and
`/goal`'s `Goal cleared.` conform as written — recorded with the broader
name-ban as a rejected alternative. The web row assertions are scoped to the
row so unrelated page text reading `permission` cannot satisfy them.
2026-07-30 18:07:35 +08:00

4.0 KiB
Raw Blame History

Agent Note: Command row copy is split between the row and the handler

Status: implemented

English | 中文

Problem

Web 命令行由一对落库的命令生命周期事件渲染出 标题 · 摘要:标题是由 command/run 重建的分派命令行(/permission workspace-write),摘要是 command/done 的原样 text(Permission preset: workspace-write.)。两半各自成文、互不知情,于是一行里命令名出现两次、参数也出现两次——最糟的一例正是用户每次用 Access chip 切换权限时得到的那一行。

Decision

命令行两半的职责互不重叠,各自只按自己那一半来写。

行标题就是裸命令名——没有 /,也没有参数。/ 属于编辑器的输入语法,不属于一条已落定的记录;参数也不该由这一行来报告:摘要已经说清了这条命令做了什么。对于 command/run 那一页已滑出客户端窗口的跨窗口节点,GenericCommandCard 仍保留 命令 兜底标题。

因此,命令 handler 的落定 text 绝不用命令自身的名字给自己的值加标签——渲染它的界面已经说过一次了。/permission 返回 preset workspace-write,裸调用时返回 current preset workspace-write (available: …),参数非法时返回 unknown preset "bogus" (available: …)。作为一行读是 permission · preset workspace-write;作为独立一句读——TUI 把同一段 text 作为通知追加——它依然说明了当下生效的是哪个预设。

这条规则禁的是标签,不是用词。Permission preset: workspace-write. 之所以出局,是因为 Permission preset: 是给一个值加的题头,而这个题头正是标题本身。恰好含有命令名的领域名词不是题头,因此保留:/plan 仍返回 Plan mode off. 与 Plan mode on. Use /plan off to leave.(plan · Plan mode off. 说的是那个模式,句尾是一条指引,不是回声),/goal 仍返回 Goal cleared.。真正被这条规则拦下的,是 handler 在自己的值前面写出 <命令名> <名词>: 的那一类。

日志本身未变:command/run 保留结构化的 name/args 拆分,因此更丰富的已注册命令行仍可从同一个节点渲染参数,无需第二条数据通道。

Alternatives considered

保留分派命令行作标题,只缩短落定文案。 参数仍会出现在分隔点两侧(permission workspace-write · preset workspace-write),而这正是被指出的重复。

从折叠行中去掉落定文案,而不是去掉参数。 这颠倒了这一行的价值:持久记录存在的意义就是结果,而错误文案将无处落脚。

由这一行从落定文案里剥掉开头的命令名。 呈现层会悄悄改写 handler 写就的文案,而任何换一种措辞表达结果的 handler 都会让这套启发式失效。

彻底禁止命令名出现在自己的落定文案里,并把 /plan、/goal 一并改写。 这种更宽的禁令代价大于收益:无论在行上还是作为独立的 TUI 通知,Plan mode off. 与 Goal cleared. 都是这些结果最清楚的句子,而满足"禁名字"所需的缩写(off.、cleared.)读起来只是残句。值得去掉的冗余是题头。

Consequences

每一条命令行都变短了,而且这条规则可扩展:新命令的作者写结果时无需知道由哪个界面渲染,任何界面也都不必再去重。代价是分派参数离开了折叠行——命令仍在执行时,行上只有名字和 执行中…——以及"不加题头"这条规则是靠评审执行的约定,而非门禁。/permission 的文案由 permission 包的命令测试钉住,装配后的行文案由 seeded-history web 预期输出钉住:因为 /permission 完全在 host 上执行,它能无密钥地抵达一条真实的落定命令行。