# 调研记录 ## 用户现象 - 输入形如 `/report/mcps?search` 的文件或路径文本时,界面显示“未知指令”,并阻止消息发送。 - `/` 快捷选择目前只在输入框第一个字符生效,而 `@`、`$` 可在输入中间生效。 ## 预期 - 未知 `/` 文本可以继续提示,但发送动作应继续完成。 - `/` 在与 `@`、`$` 相同的合理 token 边界上可触发快捷选择。 ## 仓库工作流 - Trellis 要求先建立并启动独立任务,再进入实现和质量检查阶段。 - 当前前端组件与质量规范仍是占位文档,没有额外项目级实现约束;本次以现有代码风格和回归测试为准。 - 前端交互应保持克制:沿用现有提示样式,只修正触发与发送语义,不增加新的界面层级。 - Trellis 已为本次修复创建独立任务 `07-16-composer-slash-trigger`,不会混入原有 bootstrap 或子代理卡片任务。 - `codebase-memory-mcp` 项目 `home-cc-web` 索引状态为 `ready`,包含 3191 个节点、7729 条边,可直接用于实现定位。 ## 初步代码定位 - 服务端 `handleSlashCommand` 当前对所有以 `/` 开头的输入进入 `switch`;默认分支只发送“未知指令”系统消息并要求前端恢复草稿,因此原文本不会进入正常消息处理链路。 - 前端 `sendMessage` 存在显式 `text.startsWith('/')` 分支,并为失败响应保存/恢复 slash 草稿;现有回归测试把未知 slash 视为“失败且恢复草稿”,正是用户所述的发送拦截行为。 - 需要把“是否为内置 slash 命令”的判断与普通 `/路径` 文本分开:内置命令仍走命令处理,未知 slash 可提示后继续正常消息链路。 - 快捷触发的具体解析函数尚待继续定位,需重点查看 `composer_suggestions` 请求生成以及光标前 token 匹配逻辑。 ## 快捷触发根因 - `findActiveComposerToken` 对 `/` 使用独立特判:要求整段输入 `value.startsWith('/')` 且没有换行,因此只允许首字符触发。 - 同一函数对 `@`、`$` 使用 `/(^|\s)([@$])([^\s]*)$/`,允许行首或空白后触发;这解释了三种触发符行为不一致。 - 最小一致性修复应统一 token 边界解析:`/`、`@`、`$` 都允许行首或空白后触发,token 到光标前不能含空白。这样普通路径中的内部 `/`(如 `src/foo`)不会误开菜单,而“请看 /report”能触发。 - `sendMessage` 仍用 `text.startsWith('/')` 判定命令,需新增明确的内置命令识别;未知 `/路径` 应走普通 `submitUserMessage`,服务端再提供提示或明确的非阻断反馈。 ## 最终实现与验证 - 前端 `isKnownSlashCommandText` 按第一 token、忽略大小写精确匹配 8 个内置命令;未知 `/路径` 进入普通消息/附件流程。 - `findActiveComposerToken` 统一使用行首或空白后的 `[/@$]` token 规则,并通过光标、LF、CRLF、路径内部斜杠用例。 - 服务端 `handleSlashCommand` 返回是否已处理;未知命令发送无 `preserveComposerDraft` 的提示后,以 `unknownSlash` 标志进入普通 `handleMessage`,旧客户端与 Codex App 运行中 steer 也能正确放行。 - 独立质量审查自动比较前后端完整命令集合,并确保每个服务端命令都有显式 `case`。 - 主线程复验:定向回归、完整回归、三份 JS 语法检查及 `git diff --check` 全部通过;完整回归约 30 秒。 - 并发中的“统一子代理卡片样式”任务也修改了 `public/app.js`、`scripts/regression.js`,最终总 diff 含其内容;本任务未回退或改写该部分,只按精确函数/断言范围核验 slash 改动。