技能与自定义命令

SKILL.md 从哪些目录被发现、同名时谁先被加载,技能清单怎样以系统提醒进入上下文、Skill 工具怎样读取全文;Markdown 自定义命令的参数替换与 shell 展开及其安全边界,以及内置斜杠命令在 TUI、无头模式与 App 协议里的不同面貌。

作者 David更新于 34 篇(共 47 篇)

ZCode 有两种“写一段 Markdown 就能扩展 Agent”的机制。技能是一个目录加一份 SKILL.md:模型平时只看到名字和描述,需要时调用 Skill 工具把正文读进上下文。自定义命令是一份 .md 提示词模板:用户输入 /名字 参数,模板展开成一条普通提示词交给模型,展开前还能先跑几段 shell。两者再加上 19 个内置斜杠命令,就是用户在输入框里敲 / 时能用到的全部东西。

代码分三层:发现与读取在 apps/zcode-cli/packages/adapters/src/skills/apps/zcode-cli/packages/adapters/src/commands/;装配、命令展开与 shell 执行在 apps/zcode-cli/packages/bootstrap/src/ 下的 skills.tscustom-commands.tscustom-command-prompt.tscustom-command-shell-expansion.tsbuiltin-prompt-command.tsslash-command-surface.tsSkill 工具与技能清单在 core/src/tool/handlers/skill.tscore/src/context/sections/skills.ts;终端里的斜杠命令分发在 cli/src/command-center/。插件同样能携带技能与命令,插件本身留给下一篇

怎么用

操作入口说明
列出技能zcode skillszcode skills list每条显示名字、scope/source、描述与 SKILL.md 路径;--json 输出 JSON,--verbose 附诊断
查看一个技能zcode skills inspect <name>另显示 safeToAutoLoad、读取字节数与正文
列出或查看命令zcode commands listzcode commands inspect <name>inspect 显示解析出的 frontmatter,--verbose 才打印正文
TUI 里列技能/skillzcode skills list 同一份文本
点名使用技能/skill <name> [task]改写成一条“先调 Skill 工具”的提示词
调用自定义命令/<name> [args]展开模板后作为普通提示词提交
帮助/help [command]内置命令与自定义命令一并列出

子命令分派在 apps/zcode-cli/packages/cli/src/run.ts:546zcode --help 只写了 skills listcommands listapps/zcode-cli/packages/i18n/src/locales/zh-CN.ts:19zh-CN.ts:24),inspect 没有出现在帮助里,但两个子命令都支持它(apps/zcode-cli/packages/cli/src/skills-command.ts:26apps/zcode-cli/packages/cli/src/commands-command.ts:30)。

个人技能放 ~/.zcode/skills/<name>/SKILL.md,项目技能放仓库里的 .zcode/skills/<name>/SKILL.md,两处都另认一个 .agents/skills;命令对应 ~/.zcode/commands/.zcode/commands/(外加 .agents/commands)下的 .md 文件。相关配置写在用户配置文件 ~/.zcode/cli/config.jsonapps/zcode-cli/packages/adapters/src/config/file-config.adapter.ts:61)或项目的 .zcode/config.json 里:

默认作用
features.skillskills.enabled都是 true两者同时为真才创建技能端口,否则连 Skill 工具都不注册
skills.roots[]额外技能根目录,支持 ~/ 与相对路径
skills.metadataBudget20000技能清单的字符预算
skills.includeInstructionstrue只被解析与合并,运行时没有读取它的地方
skill.<SKILL.md 绝对路径>.enablefalse 禁用单个技能
command.<命令文件绝对路径>.enablefalse 禁用单条命令

默认值在 apps/zcode-cli/packages/contracts/src/config/index.ts:313contracts/src/config/index.ts:330。桌面设置页的技能开关写的是复数形式 skills.<路径>packages/services/src/skills/skillsService.ts:568),解析配置时两种写法合并成同一张禁用表(apps/zcode-cli/packages/adapters/src/config/schema.ts:411),发现阶段直接剔除命中的路径(apps/zcode-cli/packages/bootstrap/src/skill-command-overrides.ts:5)。

技能从哪些目录来

resolveDefaultSkillRoots 按固定顺序排出根目录,每排一个就分到一个递增的 priority,步长 10(apps/zcode-cli/packages/adapters/src/skills/roots.ts:8)。核心一段(skills/roots.ts:34):

  for (const extraRoot of options.extraRoots ?? []) {
    roots.push(
      root(
        resolveConfiguredRoot(extraRoot, resolvedWorkingDirectory),
        "project",
        "zcode",
        nextPriority(),
      ),
    );
  }

  if (includeZcode) {
    roots.push(...skillRootsForBase(home, "user", nextPriority));
  }

  const projectDirectories = await resolveProjectSkillDirectories(resolvedWorkingDirectory);
  for (const directory of projectDirectories) {
    if (includeZcode) {
      roots.push(...skillRootsForBase(directory, "project", nextPriority));
    }
  }

  roots.push(...(options.extraResolvedRoots ?? []));

  return roots;
顺序根目录scope/source
1skills.roots 里的每个目录project/zcode
2~/.zcode/skills~/.agents/skillsuser/zcodeuser/agents
3从工作目录起逐级向上,每层的 .zcode/skills.agents/skills,到含 .git 的那一层为止project/zcodeproject/agents
4已启用插件的技能目录(由 bootstrap 传入)官方插件为 system/plugin,其余为 user/plugin

找不到 .git 时只看工作目录本身(skills/roots.ts:61)。每一层的 .zcode.agents 是合并而不是回退,注释写明“用户可能同时安装原生 .zcode skill 和兼容 .agents skill”(skills/roots.ts:99)。.agents 是注释里所说的“兼容”目录,名字不带任何产品前缀,ZCode 在技能和命令两处都认它;桌面设置页早先把它当成 .zcode 的后备,结果同层 .zcode 只要有一个技能,.agents 整根就从界面上消失,后来改成与 Agent 一致的合并语义(packages/services/src/skills/skillsService.ts:157)。插件技能根的 priority 从 1000 起步(apps/zcode-cli/packages/adapters/src/plugins/index.ts:104),scope 按插件来源区分(adapters/src/plugins/index.ts:704)。

同名时谁赢discoverSkills 按路径而不是按名字去重,注释说“同名技能可能来自不同技能生态或版本,不能只按 name 去重;路径才是安装项身份”(apps/zcode-cli/packages/adapters/src/skills/index.ts:80),所以同名技能会全部出现在清单里。按名字排序时排序是稳定的(adapters/src/skills/index.ts:89),loadSkill 取第一个名字匹配的条目(adapters/src/skills/index.ts:108),效果是 priority 数值小的根目录胜出。这与多数人的直觉相反:~/.zcode/skills/foo 会压过仓库里的 .zcode/skills/foo,工作目录这一层压过上层目录,插件技能排在最后,而 skills.roots 里配的目录排在所有目录之前。

ZCode 不扫描 Claude Code 的技能目录 ~/.claude/skills.claude/skills(见 Claude Code 手册的 Skills 篇)。想复用那边的技能,只能复制或软链接到 ~/.zcode/skills:用户级根跟随符号链接,注释明说这是受支持的导入方式(apps/zcode-cli/packages/adapters/src/skills/scan.ts:23)。

扫描策略

  • 只看两层:根目录自身的 SKILL.md,加上一层子目录里的 SKILL.mdscan.ts:43)。skills/engineering/foo/SKILL.md 这种分组布局不会被 Agent 发现。共享策略里的 MAX_SKILL_SCAN_DEPTH = 8 只给桌面端的递归扫描用(packages/shared/src/skill-scan-policy.ts:43),桌面设置页因此“支持分组目录”(packages/services/src/skills/skillsService.ts:991)。结果是分组目录里的技能能在桌面界面上看到,Agent 的 Skill 工具却加载不到。
  • 跳过的目录node_modulesdistbuildouttargetvendorcoverage.cache.next.turbo.venv__pycache__skill-scan-policy.ts:21),以及除 .system 以外所有以 . 开头的目录(skill-scan-policy.ts:50)。
  • 符号链接:用户级根跟随链接;插件根在根目录、子目录、SKILL.md 三个粒度一律拒绝链接,防止插件借链接读到插件根外的文件(scan.ts:16apps/zcode-cli/packages/adapters/src/skills/index.ts:141)。
  • 错误:路径不存在视为常态、返回空;权限错误等其余异常记成 skill_scan_failed 诊断,不中断其他根(adapters/src/skills/index.ts:149)。
  • 大小:描述超过 1024 个字符的技能直接丢弃(adapters/src/skills/index.ts:20adapters/src/skills/index.ts:206);Skill 工具最多读 100000 字节,超出部分截断(adapters/src/skills/index.ts:28apps/zcode-cli/packages/core/src/tool/handlers/skill.ts:16)。

SKILL.md 的格式与 Claude Code 兼容程度

frontmatter 用一个手写的扁平 YAML 解析器读:只认顶层 键: 值,缩进行一律跳过,但支持 >| 两种块标量,免得多行描述只剩一个符号(adapters/src/skills/index.ts:327)。规则如下(adapters/src/skills/index.ts:178):

  • 没有 frontmatter:名字取目录名,描述可以为空,照样加载。
  • 有 frontmatter 却缺 namedescription:记 error 级诊断,丢弃该技能。
  • when_to_use 会拼在描述后面一起进清单(apps/zcode-cli/packages/core/src/context/sections/skills.ts:61)。
  • namedescriptionwhen_to_uselicensemetadata 之外的键不报错,只让 safeToAutoLoad 变成 falseadapters/src/skills/index.ts:21adapters/src/skills/index.ts:231)。这个字段只在 zcode skills inspect 里显示,没有任何地方据它拦截加载;同样,policy.allowImplicitInvocation 恒为 trueadapters/src/skills/index.ts:234),也没有消费者。
  • 正文里的 ${ZCODE_SKILL_DIR}${CLAUDE_SKILL_DIR} 在加载时替换成技能目录(tool/handlers/skill.ts:73)。

所以兼容程度可以概括为:Claude Code 风格的 SKILL.md 能原样加载,CLAUDE_ 前缀的变量名也认,但目录不通用,控制类键不生效。仓库自己的 .agents/skills 就是例子:dep-refs 写了 disable-model-invocation: true.agents/skills/dep-refs/SKILL.md:4),agent-browser 写了 allowed-tools.agents/skills/agent-browser/SKILL.md:4),在 ZCode 里前者照样可以被模型自动调用,后者也不会放宽任何权限。

技能怎样进入上下文

技能在会话初始化上下文时发现一次(apps/zcode-cli/packages/core/src/runtime/methods/context.ts:65),之后整场会话用这份快照;输入框要展示技能时也读同一份快照,而不是另扫磁盘(context.ts:76)。清单由 buildSkillsSection 生成(core/src/context/sections/skills.ts:39):

function buildSkillsContent(skills: SkillMetadata[], budget: number): string {
  const lines = [
    "The following skills are available for use with the Skill tool:",
    "",
  ];

  const sortedSkills = [...skills].sort((a, b) =>
    skillDisplayName(a).localeCompare(skillDisplayName(b)),
  );
  const skillLines = sortedSkills.map((skill) => formatSkillLine(skill, MAX_DESCRIPTION_CHARS));
  const full = [...lines, ...skillLines].join("\n");
  if (full.length <= budget) {
    return full;
  }

  const namesOnly = sortedSkills.map(
    (skill) => `- ${skillDisplayName(skill)}${bareAliasSuffix(skill)} (file: ${skill.path})`,
  );
  return [...lines, ...namesOnly].join("\n");
}

每条是“名字、描述、(file: 路径)”,描述截到 250 个字符(skills.ts:10);插件技能显示为 插件名:技能名,后缀注明也能用裸名加载(skills.ts:75)。整份清单超过预算(默认 20000 个字符)就只列名字和路径,不会逐条丢弃。它不在系统提示词里:这一段的注入目标是 meta_user,拼成来源为 skills_listing 的附件(apps/zcode-cli/packages/core/src/context/builder.ts:282),属于请求前缀里的一条系统提醒(apps/zcode-cli/packages/core/src/system-reminder/source.ts:91)。当前工具表里没有 Skill 时(例如某些工作流子 Agent),整段省略,免得模型以为自己有一个其实不存在的工具(builder.ts:175)。提醒与缓存布局的细节见系统提示词、上下文与提醒

Skill 工具

工具输入是 skill 加可选的 args,旧写法 name 仍被接受(apps/zcode-cli/packages/contracts/src/tools/skill.ts:9contracts/src/tools/skill.ts:21),但处理函数只取 skillargs 被解析后就丢掉了(core/src/tool/handlers/skill.ts:19)。加载时 loadSkill 会重新跑一遍发现,按裸名或 插件名:技能名 取第一个匹配,读正文、去掉 frontmatter(adapters/src/skills/index.ts:95),然后包装成(tool/handlers/skill.ts:58):

  return [
    `<skill_content name="${loaded.metadata.name}">`,
    `# Skill: ${loaded.metadata.name}`,
    "",
    expandSkillContextVariables(loaded.content, loaded.baseDirectory),
    "",
    `Base directory for this skill: ${loaded.baseDirectory}`,
    "Relative paths in this skill are relative to this base directory.",
    loaded.truncated ? "[Skill content truncated]" : "",
    "</skill_content>",
  ]
    .filter((line) => line.length > 0)
    .join("\n");
};

技能目录里的附属文件由模型按“Base directory”自己去读。工具声明为只读、并发安全、无需审批,超时固定 30000 毫秒(tool/handlers/skill.ts:101tool/handlers/skill.ts:134);遥测只记录限定名、插件 ID 与来源,不带正文和描述(tool/handlers/skill.ts:52)。它只在技能端口存在时注册(apps/zcode-cli/packages/core/src/runtime/helpers/runtime-tools.ts:51),端口的创建条件就是前面表里的两个开关(apps/zcode-cli/packages/bootstrap/src/app/create-app.ts:745)。

工具说明里有一条“看到 <command-name> 标签说明技能已经加载,不要再调”(tool/handlers/skill.ts:99),但 ZCode 的代码里没有任何地方生成这个标签,这一条在 ZCode 里用不上。用户这一侧,/skill <name> [task] 并不自己读文件,而是把输入改写成一条提示词,要求模型先用 Skill 工具加载该技能再做事(apps/zcode-cli/packages/cli/src/command-center/slash-commands.ts:218)。直接输入 /技能名 的效果则取决于入口:TUI 与 -p 无头模式都只回一句 Unknown command;App 协议(桌面与 Web)找不到同名自定义命令时把原文交给模型,由模型按工具说明自己去调 Skill

图表加载中…

自定义命令:位置、名字与 frontmatter

命令根目录的排法与技能完全相同:~/.zcode/commands~/.agents/commands,再从工作目录逐级向上到 Git 根,每层 .zcode/commands.agents/commands,最后是插件的命令目录(apps/zcode-cli/packages/adapters/src/commands/roots.ts:20)。有两点不同:bootstrap 没有给命令传额外根目录,所以没有类似 skills.roots 的配置(apps/zcode-cli/packages/bootstrap/src/custom-commands.ts:91);同名命令先到先得,后来的记一条 custom_command_duplicate_name 警告(apps/zcode-cli/packages/adapters/src/commands/index.ts:71),因此同样是用户级命令压过项目级命令。

  • 名字:取相对根目录的路径,目录分隔符换成 :,再转小写,frontend/test.md 就是 /frontend:testadapters/src/commands/index.ts:270);必须匹配 ^[a-z0-9][a-z0-9_:-]{0,63}$,文件名里带点或空格的会被拒绝(adapters/src/commands/index.ts:22)。
  • 扫描:递归扫描,深度上限 12,跟随符号链接,悬空链接跳过(adapters/src/commands/index.ts:25adapters/src/commands/index.ts:242);单个文件最多读 100000 字节(adapters/src/commands/index.ts:23)。
  • 描述:取 frontmatter 的 description,没有就取正文第一行非空内容,去掉开头的 # 与列表符号;两者都没有则丢弃该命令(adapters/src/commands/index.ts:182adapters/src/commands/index.ts:362)。

frontmatter 认六个键,其余的记 custom_command_unknown_frontmatter 警告但不影响加载(adapters/src/commands/index.ts:26adapters/src/commands/index.ts:194):

实际作用
description补全列表与 /help 里的说明
argument-hint附在用法后面,如 /review <file>
skills逗号分隔的技能名;展开时在提示词开头要求模型先用 Skill 工具加载它们
disable-noninteractive只在两处生效:App 协议的 / 目录剔除该命令,zcode commands list 注上 (interactive only)
allowed-tools被解析,在 zcode commands inspect 里显示,运行时没有消费者
model同上,不会切换模型

disable-noninteractive 的两处消费见 apps/zcode-cli/packages/bootstrap/src/zcode-protocol/slash-commands.ts:43apps/zcode-cli/packages/cli/src/commands-command.ts:176-p 无头模式里没有找到对应的拦截。allowed-toolsmodel 在 Claude Code 里是有效的控制键(见 Claude Code 手册的 SkillsCommands 两篇),在 ZCode 里只是元数据。

参数替换与提示词包装

参数替换在 contracts 里(apps/zcode-cli/packages/contracts/src/commands/index.ts:138):

export function expandCustomCommandTemplate(input: {
  args: string;
  command: CustomCommandContent;
}): CustomCommandTemplateExpansion {
  const args = input.args.trim();
  const positional = splitCustomCommandArguments(args);
  let usedArgumentsPlaceholder = input.command.content.includes(ALL_ARGUMENTS_TOKEN);
  let body = input.command.content.replaceAll(ALL_ARGUMENTS_TOKEN, args);
  body = body.replace(POSITIONAL_ARGUMENT_PATTERN, (_match, index: string) => {
    usedArgumentsPlaceholder = true;
    const offset = Number(index) - 1;
    return positional[offset] ?? "";
  });

  if (args.length > 0 && !usedArgumentsPlaceholder) {
    body = `${body.trimEnd()}\n\nUser arguments:\n${args}`;
  }

  return {
    argumentCount: positional.length,
    body,
    usedArgumentsPlaceholder,
  };
}

$ARGUMENTS 换成整串参数,$1$2 换成按空白切开的第几个参数,切分支持单双引号与反斜杠转义(contracts/src/commands/index.ts:191);缺位的编号换成空串。模板里一个占位符都没用、用户却给了参数时,参数以 User arguments: 一段附在末尾,不会丢。展开后的正文前面再加两行:Run custom command /名字.Command source: scope/source.,声明了 skills 的还有两行加载要求(contracts/src/commands/index.ts:163)。最终提交给回合的是这段提示词,界面与历史里显示的仍是用户输入的原文(apps/zcode-cli/packages/bootstrap/src/app/input-facade.ts:131)。

展开入口是 bootstrap 的 resolveZCodeCustomCommandPromptapps/zcode-cli/packages/bootstrap/src/custom-command-prompt.ts:31):保留名直接放过,动态工作流灰度关闭时 /workflow 也放过(custom-command-prompt.ts:42,这个命令来自内置的 zcode-guide 插件),找不到命令时返回 undefined,原文当普通提示词交给模型。它挂在 input facade 上,每条提示词都先过一遍;在它之前还有一道内置的 /init,把输入换成一段生成或更新工作区 AGENTS.md 的长提示词(apps/zcode-cli/packages/bootstrap/src/builtin-prompt-command.ts:9create-app.ts:793),所以名为 init 的自定义命令永远不会生效。

Shell 展开与它的边界

模板里可以写两种 shell 片段:行内是感叹号后接一对反引号包住的命令,块状是以三个反引号加感叹号开头的代码块(apps/zcode-cli/packages/bootstrap/src/custom-command-shell-expansion.ts:13)。展开时每段依次执行,用标准输出(去掉末尾空白)替换原文,执行方式如下(custom-command-shell-expansion.ts:119):

  const result = await input.executionPort.run(
    {
      command: {
        mode: "shell",
        command: input.shellCommand,
      },
      cwd: input.workingDirectory,
      env: createShellExpansionEnv({
        plugin,
        sessionId: input.sessionId,
        workingDirectory: input.workingDirectory,
      }),
      outputLimit: {
        maxBufferBytes: DEFAULT_SHELL_EXPANSION_OUTPUT_BYTES,
        maxInlineBytes: DEFAULT_SHELL_EXPANSION_OUTPUT_BYTES,
        persistOutput: "none",
      },
      timeoutMs: DEFAULT_SHELL_EXPANSION_TIMEOUT_MS,
  // ...
    },
    { signal: input.signal },
  );

  if (result.status === "completed" && (result.exitCode ?? 0) === 0) {
    return result.stdout.text.trimEnd();
  }

  throw new Error(formatShellExpansionError(input.command, input.shellCommand, result));
  • 限制:每段超时 30000 毫秒,输出上限 128 KiB(custom-command-shell-expansion.ts:10);任何一段非零退出,整条命令就以 shell expansion failed 报错,不会带着半截结果进回合。
  • 环境变量:子进程拿到 ZCODE_PROJECT_DIR,有会话时加 ZCODE_SESSION_ID,插件命令再加 ZCODE_PLUGIN_ROOTZCODE_PLUGIN_DATAZCODE_PLUGIN_IDZCODE_PLUGIN_NAME;除后两个外都有对应的 CLAUDE_ 别名(custom-command-shell-expansion.ts:160)。这些是导出的环境变量,不是文本替换;命令里引用技能目录变量会直接报错,因为命令没有技能上下文(custom-command-shell-expansion.ts:193)。
  • 不经过权限系统:展开直接调用执行端口,不走工具执行器里的钩子、权限模式与审批,也不受 plan 模式约束(对照权限模式与规则执行边界)。另外参数替换发生在 shell 展开之前(custom-command-prompt.ts:59),写在 shell 片段里的 $1 会原样拼进命令行。

三个入口对 shell 展开的态度并不一致。bootstrap 的解析器总带着执行端口(create-app.ts:808),所以 App 协议与 -p 无头模式都会执行;无头模式为了不把用户的 shell 片段跑两遍,探测命令是否存在时只读文件、不展开(apps/zcode-cli/packages/cli/src/prompt-command.ts:464)。TUI 空闲时提交走 CLI 自己的展开函数,遇到这两种语法直接报“Dynamic expansion is not available yet”(apps/zcode-cli/packages/cli/src/custom-command-expand.ts:26);可一旦回合正在运行,TUI 改走 sendInput 把原文交给 App,同一条命令反而会被执行(apps/zcode-cli/packages/cli/src/tui-prompt-handler.ts:338)。

仓库里的 .zcode/commands.agents/commands 属于项目内容。克隆一个陌生仓库后,只要输入了其中某条命令的名字,它模板里的 shell 片段就会以当前用户身份执行,事先不会弹出任何审批;从代码看,这里没有类似工作区钩子那样的信任闸门(钩子的信任机制见生命周期 Hooks 与工作区信任)。

内置斜杠命令与三个入口

内置命令只有一张表:BUILTIN_ZCODE_SLASH_COMMAND_HELP_ENTRIESpackages/shared/src/zcode-slash-command-help.ts:9),/help 的文本、TUI 的补全、保留名单都从它生成。19 条按在 TUI 里的去向分组:

去向命令
TUI 本地处理,不进模型/help/login/logout/effort(别名 /variant)、/locale/language)、/mode/model/mcp/plugins/plugin)、/new/clear)、/resume/continue)、不带参数的 /skill
改写成提示词再提交/init/skill <name> [task]
交给回合,在运行时里再识别/compact/rewind/fork
专门的处理器/goal/target)、/expert/dwf

TUI 的分派在 apps/zcode-cli/packages/cli/src/command-center/create.ts:38:先用 parseSlashCommand 识别内置名字(command-center/slash-commands.ts:17),认不出的当成自定义命令,再找不到才报 Unknown command(create.ts:63)。补全列表是内置条目加自定义命令,技能不在其中(command-center/slash-commands.ts:238)。/compact/rewind/fork 在回合入口由运行时自己解析(apps/zcode-cli/packages/core/src/runtime/methods/turn.ts:105,解析器在 apps/zcode-cli/packages/core/src/runtime/helpers/commands.ts:5),各自的机制见上下文压缩检查点、回退与分叉

App 协议(桌面与 Web)是另一个面:/ 目录里的内置命令只有 goalcompactinit,外加只给 App 输入框用的 planapps/zcode-cli/packages/bootstrap/src/slash-command-surface.ts:3);自定义命令去掉 disable-noninteractive 与保留名后附在后面,来自 zcode-guide 的 /workflow 被钉在 goal 之后(apps/zcode-cli/packages/bootstrap/src/zcode-protocol/slash-commands.ts:27zcode-protocol/slash-commands.ts:67)。保留名单是全部内置名字与别名,再加 compressplanslash-command-surface.ts:19),自定义命令起了这些名字,在 bootstrap 这一层永远不会展开。桌面快捷键表里的“Command Center”(默认 CmdOrCtrl+k)是另一个东西,是界面上的命令面板(packages/shared/src/shortcutCommands.ts:63),与这里的斜杠命令分发器无关。

图表加载中…

仓库里的 .agents/skills 与产品的内置技能

仓库根目录的 .agents/skills 有 8 个技能:agent-browserai-elementsarchitecture-governancedep-refsdogfoodelectronfeature-boundary-plannerreact-best-practices,其中几个注明派生自 Vercel 的开源项目。它们是给在本仓库里干活的 Agent 用的开发工具,AGENTS.md 要求改代码前先用 architecture-governance 做架构检查(AGENTS.md:40)。因为 ZCode 本身就读项目的 .agents/skills,在这个仓库里开 ZCode 会话也能看到它们,但它们不随产品发布。

产品自带的技能全部来自官方插件:Browser Use 插件的 control-browserweb-gui-testerapps/zcode-cli/packages/browser-use-plugin/skills/);文档、PDF、演示文稿、电子表格四个插件各带一个 docxpdfpptxxlsx 技能(apps/zcode-cli/packages/bootstrap/src/app/official-plugin-definitions.ts:175);plugin-creatorskill-creator 带同名技能(official-plugin-definitions.ts:266packages/ui/src/lib/builtinSkillI18n.ts:120);zcode-guide 带配置指南、自诊断技能与 dynamic-workflows 编写指南,外加 /workflow 命令(official-plugin-definitions.ts:82official-plugin-definitions.ts:297);默认关闭的两个模拟器插件分别带 ios-devandroid-devbuiltinSkillI18n.ts:88builtinSkillI18n.ts:45)。开源仓库里只有 browser-use-pluginnode-repl-host 两个插件包,其余只有定义没有内容;superpowers-plugin 目录下只剩一份 LICENSE,第三方清单写明原先内置的插件实现已被移除(third-party/copied-components.json:241)。桌面端还能把本机的用户级技能打包同步到远程工作区(packages/services/src/skill-sync/skillSync.ts:11),见远程工作区与手机远控

下一篇:插件与官方市场——插件能带来哪些组件、清单怎样解析、官方市场的内置与 CDN 两个分区,以及插件从来源到运行时的整条装载链。

本页目录