跳到主要内容

卡与插件的关系

互不嵌套

卡目录里永远只有 requires 声明,不含插件实体。 插件单独安装、按 id 匹配。

为什么不许把插件塞进卡目录:

  • 两张卡都要同一个插件,就会有两份实体,升级要挨张卡改;
  • 「换一张卡」与「装一个插件」是两件独立的事,绑死后哪件都做不干净;
  • 卡是纯数据、免代码信任门;一旦卡里能藏代码,这条安全边界就没了。

声明的三个层次

卡对「我需要什么」的表达,从粗到细有三层,都在 requires 段(详见requires 依赖声明):

层次字段说的是
要一类能力providers[].capability「我要 TTS」——不关心谁实现
偏好某个 providerproviders[].prefer「优先用这一家,别家顶上效果会不同」
指明去哪providers[].plugins / plugins[]「装这个插件就能得到上面那个 provider」

这套分层让卡不锁死实现:收卡人机器上没有作者点名的那家 provider 时,系统可以按声明回落到别家(除非作者显式写 fallback: false),并且知道该引导用户装哪个插件。

一起分发:组合包

互不嵌套说的是安装后的形态,不妨碍分发时打包在一起。导出 .channekcard 时,打包器可以按 requires 把已安装的插件一并收进包里;导入时拆包,卡进卡库、插件走各自的安装与信任门,互不越界。

注意

导入向导会逐个列出包内插件的 id、版本、信任级与权限清单,要求用户逐项确认——导入一张卡可能装上代码,绝不随卡静默安装。作为卡作者,别指望「藏在包里」能跳过用户的知情同意;作为收卡人,看到确认清单再点安装。

skill 跟着所有者走

给 AI Agent 看的方法论文档(skill)同样按归属分发:

  • 「某个插件怎么用」的 skill,住插件包里,跟插件走;
  • 「某个频道特有的流程方法论」,住卡声明的 skill 目录里(layout.cardAssets.libraries.skills),跟卡走。

打开频道时,应用把两处的 skill 摆到该频道的 .claude/skills/ 下,供用户自己的 AI Agent 读取。执行主体是用户的 Agent,应用本身不执行 skill。 同名时卡里的优先——频道的具体打法覆盖插件的通用说明。