Skip to content

[Tech] 内置命令名单双份硬编码(renderer switch ↔ BUILTIN_SLASH_COMMANDS),缺一致性守卫(#93 follow-up) #95

Description

@Jaxton07

#93 的 follow-up(该 PR 已合并)。#93 定下的规则是「跨来源同名命令只保留执行时真正命中的那条,优先级 内置 > 扩展 > skill > 模板」,这个优先级的第一环「内置」现在由两份互不相干、也没有测试连起来的硬编码名单维持。

两份名单

  1. packages/desktop/src/renderer/src/components/composer/use-composer-send.ts:75 —— 渲染端对 / 开头的消息先做 switch 拦截,case 只有 4 条:compact / name / export / settings(命中就调 pi.compact / setSessionName / exportSession / 打开设置,不进 SDK)。
  2. packages/backend/src/slash-commands.ts 的 BUILTIN_SLASH_COMMANDS —— 同一批 4 条,mergeCommands 用它去挤掉同名的模板/扩展/skill。

目前两边恰好一一对应(已 grep 全仓库确认没有第三处 / 前缀特判),但没有任何测试或类型把这份对应关系钉住:

  • 只在 renderer 的 switch 里加一个新内置命令 → 它不在 BUILTIN_SLASH_COMMANDS 里 → 同名扩展/模板照样被列出来,用户点它跑的是内置(拦截在前),菜单标注也是错的。
  • 只在 BUILTIN_SLASH_COMMANDS 里加 → 名字被认领、别人的命令被隐藏,但实际发出去时 renderer 不拦、SDK 会给到扩展 → 列表标的来源 = 假的。

两种都是静默失真,不报错、只有用户自己撞上。

建议

  • 把内置命令名提到 packages/shared(例如 BUILTIN_SLASH_COMMAND_NAMES,或复用一份 SlashCommandInfo 表的 name 字段),backend 的 BUILTIN_SLASH_COMMANDS 与 renderer 的 switch 都从它取值/校验,让「只改一边」编译期就暴露。
  • 退一步也可以:加一个测试断言 renderer 拦截的名字集合 === BUILTIN_SLASH_COMMANDS.map(c => c.name)(renderer 不能 import backend,可能需要 shared 里的共享常量做中转)。

顺带(可选,不必一起做)

被挤掉的命令目前是静默消失。pi CLI 的做法是补全里跳过 + 发一条诊断(modes/interactive/interactive-mode.js:450-459)。桌面端已有 getLoadedResources 这个诊断出口(pi-backend.ts:867,已列出每个扩展的 raw commands),要加提示有地方放。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions