Repository navigation
[REQ-125][CODE] 斜杠命令 chip 增加技能/MCP 类型分型(橙技能/紫 MCP 变体) #582
Description
Activity
- addedtype:featureNew user or system capabilityNew user or system capability
on Jul 25, 2026 - added a parent issue
on Aug 6, 2026 对帧订正(主 session,2026-08-12)—— 缺的不是样式,是数据
只读对帧勘破结论(全文在 #538 的评论里)。缺口仍在,而且比票面深;锚仍权威(8-10 那次只碰了活稿的
③ 段,#user的data-k="skill"/data-k="mcp"两帧与 design.css 的橙紫两条都在),
7-24 的 E3/E4 旧图仍可用 —— 这一票是五张里唯一证据能复用的。但它今天做不了,因为数据面不存在:
- 今天只有一个 chip 样式(
session-timeline-view.tsx:564,567、session-timeline.css:487),没有变体; - 真正的堵点在上游:
timeline-model.ts:118-123的TimelineSlashOrigin只有
{assistantMessageID?, command, arguments?}—— 没有任何类型或来源字段,
slashOriginForTurn(同文件 585-604)也只透传这三个。票面写「如需类型数据面,timeline-model.ts」,
而那里只是消费端。 - 2026-08-09 已批基线新立了一条原则(§6/T3):来源标记只读持久化的 identity 与 authority,
禁止从名字反推。橙/紫也是一次来源声明 ⇒ 不能靠解析命令字符串猜。
这条原则在 7-24 定票时还不存在。
⇒ 本票要么先补数据面(捕获侧把类型/来源随 slash origin 一起持久化),要么等那件事另有归属。
开工前先把这一段的归属定下来,否则实现方会走上「解析命令字符串」那条被基线明令禁止的路。- 今天只有一个 chip 样式(
- added a commit that references this issue
on Aug 13, 2026 归属勘破(只读,2026-08-13)—— 票面前提被推翻:数据面已经存在,而且已经在手里了
上一条订正说「缺的不是样式,是数据」。「缺样式」那半句成立;「缺数据」那半句不成立。
把「用户敲/xxx→ chip 出现」整条链逐跳读完并跑了一次真实产物之后,结论是:引擎早就把「这是技能 / 这是 MCP / 这是普通命令」明明白白告诉了桌面端,
而且就在 composer 已经发出的那一次请求的返回值里。我们拿到之后直接扔了。这和
#620是同一个形态(洞其实不存在,上游早给了能力只是没人用)。
1. 今天这条链长什么样
- 用户在输入框敲
/review pr 12→routeSlash(composer-state.ts:263)拆成{name, args}。 alpha-composer.tsx:1488先调c.command.list({directory})把命令清单拉下来,
用cmds.some(x => x.name === slash.name)确认这条命令存在。- 存在 →
c.session.command({...})发给引擎;拿到返回的 assistant messageID。 alpha-composer.tsx:1507回调onSlashCommand({sessionID, directory, command, arguments, assistantMessageID})。session-composer-dock.tsx:184→recordSessionSlashOrigin(...)记进
session-slash-origin.ts的一个 solid signal。- 时间线
slashOriginForTurn(timeline-model.ts:585)按 assistantMessageID 对齐回合 → 出 chip。
类型信息就是在第 2 步和第 4 步之间丢的。 第 2 步那个清单里每一条命令都带着类型,
第 4 步只挑了name和args往下传。2. 引擎侧到底知道多少(实读 + 实跑)
packages/opencode/src/command/index.ts:22-32的命令清单结构里有这一行:source: Schema.optional(Schema.Literals(["command", "mcp", "skill"])),
而且它不是名字反推出来的 —— 注册表分三段循环各自钉死:配置命令写
"command"(:96)、
MCP prompt 写"mcp"(:108)、技能写"skill"(:140)。是注册方自己的声明,正是基线要的那种 authority。三条实测(不是读代码推断的):
- 实跑当前代码生成一次 v1 契约(
bun run dev generate,2026-08-13):
Command的 schema 里确实有"source": {"type":"string","enum":["command","mcp","skill"]}。
仓里 checked-in 的packages/sdk/openapi.json与实跑结果逐字节一致。 - 桌面端用的那个 SDK 类型里也已经有了:renderer 走
@opencode-ai/sdk/v2/client,它 re-exportpackages/sdk/js/src/v2/gen/types.gen.ts,
第 2378 行export type Command = { ... source?: "command" | "mcp" | "skill" ... }。
⇒ 不需要 regen、不需要as any、不需要补类型,今天写entry.source就编译得过。 c.command.list走的是 v1 的GET /command(v2 sdksdk.gen.ts:2184明写),
返回Array<Command>,不是缺字段的CommandV2Info。这一跳我特意查了,因为两条命令面
长得很像而其中一条确实没有source。
分三种问的答案:
- 技能 —— 引擎知道,形状是
source: "skill",name就是技能名(cloudflare),干净可用。 - MCP —— 引擎知道它是 MCP(
source: "mcp"),但不知道是哪个 server(见下面第 4 节)。 #878那套 identity 快照 —— 用不上。 它是ToolPart的东西,
ToolIdentitySource枚举是builtin|builtin-v2|plugin|mcp|host,里面根本没有skill
(模型自己调技能走的是内置skill工具,技能名是参数不是身份)。斜杠 chip 是用户消息行,
不是工具卡,两套词汇不通用。别去接它。
3. 归属:一个上游文件都不用碰
按
scripts/north-star-guard.sh的口径(UPSTREAM_PATHS = packages/{opencode,core,server,tui,sdk,protocol,schema,client}):要动的文件 在上游吗 alpha-composer.tsx(:512 类型、:1488.some→.find、:1507 多传一个字段)否 session-composer-dock.tsx(:184 透传)否 session-slash-origin.ts(记录里多一个字段)否 timeline-model.ts(:118 类型、:585 校验后透传)否 session-timeline-view.tsx(:493chipInner分型、:564/567data-k)否 session-timeline.css(:487 起两段变体)否 i18n/{zh,en}.ts(两条新文案)否 对应测试 否 全部落在
packages/ui-mac,守卫零风险(刚跑过north-star-guard.sh:
✓ zero upstream package edits)。配色 token--a-orange(-subtle)/--a-purple(-subtle)
在tokens.css明暗两套都已存在(:67-70 / :217-220),不用新造。⇒ 这是一张 CODE 票,不是 DECIDE 票,而且是 S。 唯一需要 owner 点头的只有下面第 4 节那一件事。
4. 唯一真的缺口:E4 那张帧要「server + 远端名」两段,而线上只给了一段
稿子
#user帧1 的 MCP chip 是这样画的:图标 +MCP ·+ name=context7+ args=resolve-library-id。
但引擎给 MCP prompt 注册的命令名是一个合成键:
sanitize(server) + ":" + sanitize(promptName)(packages/opencode/src/mcp/catalog.ts:108),
也就是context7:resolve-library-id一整串,Command里没有单独的 server 字段,
线上也没有任何一条路由列 MCP prompt 清单(GET /mcp只给 server 状态)。技能那半张(E3)完全不受影响,今天就能按稿做。 需要裁的只有 E4 的这一刀:
- 4a 按
:切开(零上游、结构上安全 ——sanitize把两侧的:都洗掉了,分隔符不会歧义)。
代价:①这确实是「从名字拆」,和基线那条原则擦边;②拿到的是洗过的 server 名
(配置里叫my server会显示成my_server)。 - 4b 切开 + 拿
GET /mcp的 server 键集合对一次(把「拆」变成「在权威集合里认」)。
代价:多一次请求;两个配置键a-b和a_b洗完撞车时仍分不开。 - 4c 不切,整串当 name 显示(
MCP · context7:resolve-library-id)。零推断、零风险,
但与稿有肉眼可见的差异 —— 需要改稿或接受偏差。
我的建议:4c 先落地、4a 作为可选增量。理由是这一票的价值 95% 在「橙 / 紫一眼分得清」,
而 4c 已经百分之百交付了那件事;为最后 5% 的排版去碰一条基线原则不划算。5. 顺带勘破出来的一件事(不属于本票,但请知悉)
session-slash-origin.ts是一个 renderer 内存 signal,不落盘。也就是说
今天这个 chip 本来就活不过一次重启 —— 重开会话根本看不到它。
所以订正块里说的「捕获侧持久化」在现状里并不成立;好消息是这反而让本票更安全:
数据缺席即零渲染,回放永远不会显示一个错的来源(基线 T4 天然满足)。
坏消息是「chip 重启后消失」是一个今天就存在、且比本票大得多的问题,
要修得让引擎把来源写进消息或另建持久层(会碰schema/src/v1/session.ts与
session/prompt.ts—— 那两个文件 ADR-041 已经收编,但仍是 L 级)。建议另开票,不要塞进 #582。6. 四条路的对照
# 做什么 动哪些文件 上游 fork-sync 代价 先例 P1 ✅推荐 消费已有的 source,E3 按稿、E4 取 4c只有 packages/ui-mac那 8 个零 零 #620(洞不存在,上游早给了)P2 P1 + E4 按 :切开还原稿子同上 零 零 无;需 owner 对「拆合成键算不算反推」表态 P3 让引擎在 Command.Info里多给一个 server/originopencode/src/command/index.ts(未被任何 exclude 覆盖)+ 重生 sdk 类型 + openapi是 新 ADR + 守卫和 alpha-ci.yml 两处同步加 exclude( local-gate-parity.test.ts会判)+ 每次 fork-sync 都要重解冲突ADR-041 收编那 20 个文件 P4 把来源持久化进消息,让 chip 活过重启 schema/src/v1/session.ts、session/prompt.ts(两者已被 ADR-041 收编)+ ui-mac是(已登记) 中 ADR-041 / #878建议:走 P1,本票即刻可开工,S 级,单 PR。 P4 另开票。P3 只有在 owner 认为
E4 必须逐像素对稿、且 4a/4b 都不可接受时才值得。7. 实现方开工第一件事(别跳)
我验的是契约(实跑生成的 v1 OpenAPI + 桌面端在用的那份 SDK 类型 + 注册表三处赋值),
没有起一个装着真 MCP server 和真技能的引擎去看那个 JSON body。
所以第一步请花五分钟:对着真在跑的引擎curl /command,确认返回体里
技能条目真的带"source":"skill"、MCP 条目真的带"source":"mcp",再动手。
判据必须是看见真实响应,不是「类型里有」。- 用户在输入框敲
- added a commit that references this issue
on Aug 13, 2026
Parent requirement: #538
负责 AC:#538 AC1/AC3(视觉一致)—— 矩阵行 E3(技能 chip)/E4(MCP chip)双主题与稿一致。
边界:
packages/ui-mac/src/renderer/alpha-ui/session-timeline/session-timeline-view.tsx(cmd-chip 渲染分型)、session-timeline.css;如需类型数据面,(订正:那里只是消费端,数据面缺在捕获侧)。timeline-model.tsOut-of-scope:G15 技能执行卡形态(另票)、E1 展开体口径冲突(owner 裁决项)、E8 连接器 chip(另票)。
退出条件:E3/E4 按 CT
#user帧1 形态(橙色技能变体、紫色 MCP 变体 name+args)+ 明暗双主题一致 + 测试绿。现状(矩阵批2 发现6,基点 alpha@7281627ed):斜杠 chip 无类型分型 —— 技能/MCP 均渲染为通用「运行命令」chip;设计有橙色技能、紫色 MCP 变体(TL-05 分类)。
docs/design/current/conversation-timeline/design.html#user帧1(矩阵行 E3/E4)docs/verification/2026-07-24-req125-session-visual/shots/E3-{light,dark}-harness.png、E4-{light,dark}-harness.pngdocs/verification/2026-07-24-req125-session-visual/matrix.md批2 发现6