命令是输入 /名称 才执行的固定步骤。Claude Code 的新写法是把它写成技能 .claude/skills/<名称>/SKILL.md,并在前置元数据里加 disable-model-invocation: true——只有人输入斜杠时才会用到。旧的 .claude/commands/*.md 仍会作为同名命令加载;两边同名时技能优先。本课新写的命令一律放 .claude/skills/。
会在三种情况下打开这一页:想把一段固定步骤固化成一条斜杠命令 → 先过「建命令之前先问三句」,再照四步建;输入 / 找不到它,或它没等人叫就自己跑了 → 看「命令不响应的四种现象」;从 Cursor 或 TraeCode 迁命令过来 → 看「命令在三个工具里的写法」。
最容易写错的是两处:一是在 .claude/commands/ 下新建文件,以为那是新写法,结果同名技能并存时被技能覆盖,改了旧文件没有任何反应;二是步骤还没定下来就先建命令,/check-scope 每次跑出来的判断都不一样。步骤照着做不完,就先别建文件。
不输斜杠、只问一句「要不要核对范围」,这条命令会自己跑起来吗?
答「会跑」,说明 disable-model-invocation: true 漏写了,它现在是普通技能。补上这一行,再开一轮新对话确认。
命令不是给助手用的能力,是给人按下去的快捷方式。判断标准只有一条:这几步每次都要照着做,而且顺序固定。
disable-model-invocation: true。助手自己该做、不用人喊的,写成普通技能,见 技能。
README 的「当前阶段」。指不到文件的判断不要写。
.claude/skills/<名称>/SKILL.md,文件名必须是全大写的 SKILL.md。name 与目录名一致;description 写明「用户输入 /名称 时使用」;加上 disable-model-invocation: true。/check-scope,应能正常执行。git mv .claude/commands/check-scope.md .claude/skills/check-scope/SKILL.md 迁到技能目录。
边界:命令只在人输入斜杠时执行,所以它挡不住助手自己动手。需要百分百拦住的(例如不读 .env),放 钩子,不放命令。
三处的差别集中在「新命令写到哪个目录、叫什么名字」。TraeCode 没有技能形式的命令,文件名本身就是调用名。迁之前先对一遍目录名,迁完输入一次 / 确认它在列表里。
| 项 | Claude Code | Cursor | TraeCode |
|---|---|---|---|
| 新写法 | .claude/skills/<名称>/SKILL.md 加 disable-model-invocation: true | .cursor/skills/<名称>/SKILL.md 加 disable-model-invocation: true | .trae/commands/<名称>.md,文件名就是调用名 |
| 旧写法 | .claude/commands/*.md 仍作为同名命令加载;同名时技能优先 | .cursor/commands/*.md 仍能加载 | 无旧写法 |
| 个人位置 | 无对等注意项,个人命令并入 ~/.claude/skills/ | 无对等位置 | ~/.trae-cn/commands |
| 目录深度 | 按技能目录规则 | 按技能目录规则 | 项目命令最多嵌套 3 层目录 |
| 调用方式 | 输入 / | 输入 / | 输入 /,从 Commands 里选择 |
| 名称约束 | 技能 name 建议与目录名一致 | name 与目录名相同,只用小写字母、数字和连字符 | 文件名即名称 |
本课只保留一种落点:Claude Code 写成带 disable-model-invocation: true 的技能。旧目录在迁移期间允许存在,但同名两份必须在同一次合并请求里清掉一份。
第一份是本课推荐的新写法,在对话里输入 /check-scope 触发,它先看 README 里写明做什么、不做什么。第二份是旧写法的格式,留着它只为看懂存量仓库,新写的不要照它建。
disable-model-invocation: true 让它只在人输入 /check-scope 时执行。判据指向 README.md 的「当前阶段」。建完开一轮新对话,不输斜杠问一次、再输斜杠跑一次,两端都对才算配好。
--- name: check-scope description: 判断这次改动是否越出当前阶段已经写明的范围。用户输入 /check-scope 时使用。 disable-model-invocation: true --- 只做 README 里写明的角色和能力,数据按登录用户的所属范围隔离。 当前阶段有哪些能力,以 README.md 的「当前阶段」一节为准。 产品里给最终用户使用的功能,不是仓库里的技能文件。 不做:家长端、多校区运营、学科交易市场。 先列出这次会改的目录。 再逐条说明:哪条在上面的范围内,哪条该停。 不要为了「顺便」加上范围内没有的角色或存储。
旧命令就是一段纯文本,没有前置元数据,文件名即命令名,输入 /release-note 触发。同名技能存在时,这份会被忽略。用 ls .claude/commands .claude/skills 确认有没有同名两份。
读最近的合并请求与提交记录,按 feat / fix / chore 分组,生成一段发布说明。 只写已经合并的内容,不写计划。 每条一行,带合并请求编号。
迁移存量命令时改名要一起改:git mv .claude/commands/release-note.md .claude/skills/release-note/SKILL.md,再补上前置元数据与 disable-model-invocation: true。两份同名的,以 .claude/skills/ 那份为准,旧的那份删掉。
命令出问题多数不是写错内容,是没被识别、没被选中或选错了那一份。按「现象 → 原因 → 修法」对号入座,改完开一轮新对话再验一次。
| 现象 | 原因 | 修法 |
|---|---|---|
在 .claude/commands/check-scope.md 里改了步骤,输入 /check-scope 却没变化 | 同名技能 .claude/skills/check-scope/SKILL.md 优先,旧文件被忽略 | 改技能那份,或删掉旧文件;用 ls .claude/skills/check-scope .claude/commands 2>/dev/null 确认同名两份是否并存 |
| 建完命令,助手没等人输入斜杠就自己执行了核对范围 | 漏写 disable-model-invocation: true,它被当成普通技能按 description 加载 | 前置元数据补上 disable-model-invocation: true,并在 description 里写明「用户输入 /check-scope 时使用」 |
/check-scope 每次输出不一样,有时直接放行越界改动 | 步骤没固定,判断留给了模型自由发挥 | 把正文改成固定编号的步骤,每条判据指向 README.md 的具体小节 |
输入 / 时列表里没有 check-scope,提示未知命令 | 路径或文件名不符,例如目录写成 .claude/skill/,或文件写成 skill.md | 确认路径是 .claude/skills/check-scope/SKILL.md,文件名全大写 |