Dart Skills CLI 1.0 :AI 时代的 Dart 交付支持

最近 Dart 发布了 skills CLI 1.0 版本,这个工具其实最早由 Serverpod 团队开发,一个做后端的 Dart 框架,最近看也看到一些不错的 Dart 全栈式框架,现在这个 CLI 正式转交给了 Dart 团队维护和发布。

表面上看这个 CLI 做的事情还挺简单的,主要就是 Dart、Flutter package 可以在根目录增加一个 skills/ 文件夹,package 发布到 pub.dev 时会把这些 Agent Skills 一起带出去,用户只要执行一次 dart run skills@ get,Claude Code、Cursor、Codex、Cline、Copilot 之类的 coding agent 就能加载到这个 package 提供的使用说明

所以这一点 Flutter 和 Dart 又开始激进走在 AI 浪潮上,现在 Dart 已经把 AI 如何使用一个库作为 package 本身需要交付的内容。

以前发布一个 package 主要发布源码、类型定义、README、API 文档、example 之类,现在可以再加上一层面向 Agent 的程序化知识,包括:

  • 什么时候应该采用某种 API
  • 推荐的工程结构
  • 容易踩坑的组合
  • 错误处理方式
  • 可以执行的辅助脚本
  • 复杂任务应该按照什么流程完成

以前其实也可以在 package 里放 skills ,但是过去 Skill 最大的问题,主要还是它和依赖版本脱节,一般 Skills 的格式很轻:

一个目录、一份 SKILL.md,再按需要加入 scripts/references/assets/

比如 Dart 和 Flutter 官方之前就已经分别维护自己的 Skills 仓库,然后可以通过类似下面的方式进行安装:

bash 复制代码
npx skills add dart-lang/skills --skill '*' --agent universal
npx skills add flutter/agent-plugins --skill '*' --agent universal

但是这种方式只适合安装「怎么开发 Flutter」「怎么写 Dart 单元测试」之类的通用技能,如果是在一个 package 生态里就很麻烦了,因为 Git 仓库里的 Skill 和项目正在使用的 package 版本没有天然对应关系

比如项目依赖的是某个库的 3.2.1

yaml 复制代码
dependencies:
  some_package: ^3.2.1

模型自身可能见过 2.x 的代码,网上文档可能已经更新到 4.x,GitHub 上独立维护的 Skill 又可能按照 main 分支写,这种情况下最后 Agent 可能会同时拿到了三套时代不同的信息,时不时就写出一些奇怪的组合。

就算开发者已经安装 Node.js、能够正常使用 npx skills,还是存在 discoverability 和 package version support 两个缺口,特别是后者,用户怎样保证 Agent 使用的 Skill 与当前项目实际使用的 package 版本一致?

所以 Dart CLI 的 skills 1.0 给出的办法就是把 Skill 就放进 package 发行物,比如:

perl 复制代码
my_package/
├── lib/
├── skills/
│   ├── my-package-routing/
│   │   ├── SKILL.md
│   │   ├── scripts/
│   │   ├── references/
│   │   └── assets/
│   └── my-package-testing/
│       └── SKILL.md
└── pubspec.yaml

package 作者升级 API 的时候,需要同时修改对应 Skill,然后在执行 dart pub publish 的时候,skills/ 会随着 package 一起进入发布归档,这时候项目解析到哪个 package 版本,本地就拿到的就是那个版本附带的 Skill。

这里其实就有了一个很有意思的变化,比如以前 package 的版本号约束的是"代码和 API",现在同一个版本号开始间接约束 AI 应该怎样理解和操作这套 API。

官方给出的实现流程就是 dart run skills@ get ,CLI 会先确保项目依赖已经解析,然后读取项目生成的 package_config.json ,这个文件本来就记录了当前项目每个 package 实际在硬盘里的位置,所以 skills` CLI 可以直接定位当前项目真实使用的 package 目录。

然后它会进入 package 根目录找 skills/,扫描包含 SKILL.md 的 Skill 同时校验名称,比如 package 叫 serverpod,Skill 可以叫:

css 复制代码
serverpod-code-generation
serverpod-api-design

但是不能只写 code-generation ,原因是所有依赖最终可能把 Skill 安装进同一个 Agent Skill 空间,所以名称需要带 package 前缀避免冲突,所以对于名为 my_package 的 Dart package,应该用类似 my_package-routingmy-package-routing

发现 Skill 后,CLI 不会每次全部覆盖,它会把当前 package 内的 Skill 与之前管理的状态进行比较,判断哪些是新增、更新、删除或者此前跳过的 Skill,然后让用户选择,状态记录在:

arduino 复制代码
.config/dart_skills/skills_config.json

所以再次运行 dart run skills@ get 的时候,实际上是承担了类似"同步 AI instructions"的作用,官方文档给出的完整过程可以概括成下面这张表:

阶段 skills CLI 做的事情
依赖解析 根据 Dart 当前项目解析结果确定直接依赖
Package 定位 package_config.json 找到当前实际使用的 package
Skill 发现 查找 package 根目录中的 skills/*/SKILL.md
校验 检查 Skill 名称与 package 名称前缀
状态比较 对比已经安装、更新、删除或跳过的 Skill
Agent 适配 根据项目中的 Agent 安装到对应目录
状态记录 写入 .config/dart_skills/skills_config.json
后续同步 再次执行 get 时进行增量更新

现在这个 CLI 已经支持了多种 coding agent 的实际目录,比如:

  • Claude Code 用 .claude/skills/
  • Cursor 用 .cursor/skills/
  • Cline 用 .cline/skills/
  • GitHub Copilot 用 .github/skills/
  • Codex 和通用 Agent Skills 目录使用 .agents/skills/

一个 package 的开发者只要维护一份符合开放 Agent Skills 规范的 Skill,CLI 负责把它放到各个 Agent 能发现的位置。

另外有一个需要注意的是,CLI 只会从项目的 直接依赖 immediate dependencies 安装 package Skills,没有把整个传递依赖树全部变成 Agent 指令来源,所以只会处理你直接依赖的 package ,间接依赖的不会自动处理

另外 skills CLI 1.0 也没有试图替代 Git Skill,比如官方就保留了:

arduino 复制代码
dart run skills@ add <git_repository_url>

GitHub 上与 Dart package 无关的通用 Skills 还是可以安装,而且已经通过 add 添加的仓库,以后运行 get 时也可以一起检查更新,Dart 官方甚至专门做了兼容,很多 skills.sh 页面上原来写成 npx skills add ... 的命令,可以直接把前面的 npx skills 换成 dart run skills@ 继续使用。

另外Dart 官方还明确区分了两个目录:

  • skills/ 主要用于 package 消费者,会随 package 发布
  • .agents/skills/ 用于维护 package 自己的开发团队,不会发布给消费者

所以也不需要担心项目里存在多个来源导致污染。

然后 Dart 你现在也可以通过下面命令直接生成模板:

arduino 复制代码
dart run skills@ create \
  -n <skill_name> \
  -d "<skill_description>"

最后,skills 在 1.0 的开发过程里也加入 「安装时检查 package security advisories」 的机制,同时限制了 package Skill 来源到直接依赖, 不过从工程上看,团队还是需要把 Skill 当成依赖内容的一部分进行审查,特别是里面存在可执行脚本、修改项目文件或者调用外部命令时,不然还是容易存在安全风险。

相关推荐
Hilaku1 小时前
为什么技术极强的前端,往往当不好前端 Team Leader?
前端·javascript·程序员
Knight_AL1 小时前
EasyExcel 导入模板踩坑:row.add(““)导致文本格式失效与单元格保护问题解决方案
java·前端·easyexcel
2501_916007471 小时前
使用Apple Dashboards显示和自定iOS应用性能指标与数据可视化指南
android·ios·小程序·https·uni-app·iphone·webview
Csvn1 小时前
模板字面量类型:用类型做字符串的正则
前端
倾颜2 小时前
AI Chat 长会话性能实践:消息虚拟化、动态高度与流式滚动设计
前端·react.js·node.js
幸运小圣2 小时前
SSE 与 WebSocket 新手入门:前端实时通信完全指南【JavaScript】
前端·javascript·websocket
艾伦野鸽ggg2 小时前
25级开学 JS 考核题解
前端·javascript
蜡台2 小时前
# 已解决|MySQL 8\.4\.11 密码正确仍报错1045 \(28000\) Access denied 终极修复方案
android·mysql·adb
JMchen1232 小时前
2026年六款主流AI编程工具深度实测:Cursor、Copilot、Claude Code等对比与选型思考
android·kotlin·copilot·ai编程·开发工具·cursor·claude code