魔棒解析 GitHub Skill 入库(Skill Import)¶
状态:首版已实现。对应 #118。魔棒(⇧⌘I)除论文标识符外,还能识别 GitHub 仓库链接 /
npx skills add指令,把 Agent Skill 下载到当前 Vault 的.agents/skills/<name>/。相关:paper-import.md、agent.md。
1. 背景与现状¶
- 魔棒输入的类型识别完全在 Host 侧:
crates/agentero-core/src/features/paper/scholar_api/sources/skill.rs的extract_skill_source()(SkillSource,识别为skillkind,不入 resolver 表,但由scholar_api::identifiers统一 re-export)和import::identifiers::extract_primary_identifier()(其余标识符走scholar_api::identifiers::resolver静态表)。Skill 识别发生在普通 URL 分支之前,GitHub 链接不会再被送入 Translator/web。 - 前端不做识别,只切分多条输入(
src/components/sidebar/vault-sidebar-header.tsxparseLookupTexts()),经lookup_import_batch(src-tauri/src/features/import/commands.rs:17)进入import_by_identifier_batch。 - Skill 目录约定已存在:
vault/.agents/skills/<id>/SKILL.md(YAML frontmattername/description,解析见src-tauri/src/features/agent/prompt/skills.rsparse_skill_metadata);ensure_vault()播种 bundled skills,并按 frontmatter 整数version升级第一方 Skill(盘上版本低于模板则覆盖;无version/ 同版本 / 更高版本不覆盖)。 - 文件树中
.agents是 eager 目录(src/lib/vault/tree.tsTREE_EAGER_ROOT_NAMES/TREE_ALLOWED_DOT_NAMES),写入后refreshTree即可见。 - 仓库内没有任何 git clone / npm 逻辑;可复用的下载基础在
crates/agentero-core/src/features/paper/import/download.rs:http_get_bytes_with_progress()(reqwest + 进度事件)与 arXiv e-print 的 tar/gzip 安全解压(extract_tar_safe/sanitize_tar_path,防路径穿越)。
社区规范(2026)¶
- Skill = 自包含目录:
SKILL.md(必需,frontmattername≤64 小写字母数字连字符、必须与目录名一致;description≤1024)+ 可选scripts/references/assets/。规范见 agentskills.io/specification。 - 事实标准安装器为
npx skills(vercel-labs/skills):npx skills add <owner>/<repo> [--skill <name>],装到./.agents/skills/(通用目录,与 Agentero 一致);skills.sh 页面复制出来的就是这条命令。 - 分发主体是 GitHub repo(单 skill repo 或 monorepo 如
anthropics/skills),npm 包分发非主流。
2. 输入形态识别(pattern 枚举)¶
新增 SkillSource 识别,插在 extract_primary_identifier() 的 URL 短路之前(或在 URL 分支内按 host 细分)。按优先级:
| # | 形态 | 示例 | 解析结果 |
|---|---|---|---|
| 1 | npx skills add … 指令 |
npx skills add vercel-labs/agent-skills --skill frontend-design |
剥出 source + --skill 过滤(可多个;'*' = 全部) |
| 2 | GitHub repo 根 | https://github.com/anthropics/skills(含 .git 后缀) |
owner/repo,默认分支 |
| 3 | GitHub tree URL | https://github.com/openai/skills/tree/main/skills/.experimental/create-plan |
owner/repo + ref + 子目录 |
| 4 | github: 前缀 |
github:owner/repo |
同 2 |
| 5 | skills.sh 页面 URL | https://skills.sh/<owner>/<repo>/<skill> |
owner/repo + skill 过滤 |
不做(首版):GitLab、SSH 形态(git@…)、裸 owner/repo shorthand(与论文标识符歧义太大,如 10.1234/abc)、.well-known skill 源、npm 包名。尾部 #<ref> fragment 支持指定分支/tag。
判定为 SkillSource 的条件从严:host 必须是 github.com / skills.sh,或整条输入以 npx skills add 开头;其余仍走论文 Url 路径,避免误伤网页论文入库。
3. 下载与落盘策略¶
首版只走 codeload tarball,不依赖本机 git / node:
GET https://codeload.github.com/{owner}/{repo}/tar.gz/{ref}(ref 缺省时先经api.github.com/repos/{owner}/{repo}拿默认分支);复用http_get_bytes_with_progress报进度。- 已走 Host 网络代理(
networkProxy*)。 - Settings → 通用 → GitHub 镜像(
githubMirrorEnabled/githubMirrorBaseUrl):从内置预设列表中选择一个 URL 前缀镜像;直连失败(超时/连接错误/5xx/429)时回退{base}/https://api|codeload.github.com/...(如https://gh.llkk.cc)。4xx(如 404)不回退。与网络代理正交。 - 解压到临时目录(复用
extract_tar_safe系安全逻辑),递归扫描**/SKILL.md: - 有子目录约束(tree URL /
--skill)→ 只取匹配项; - repo 根或指定路径发现 Skill → 返回候选列表,前端弹选择(见 §4)。
- 校验 frontmatter:
name合法且与目录名一致;不一致时以name为准命名目标目录。frontmatter 解析统一走crates/agentero-core/src/frontmatter.rs(frontmatter_block+scalar_field,支持引号、>/|折叠块、多行续行、CRLF,只读顶层键)。description超过 1024 字符时按字符截断展示,不再拒绝安装;单个SKILL.md解析失败只跳过该候选,整个来源没有可用 Skill 才报错。见 bug_fix/skill-import-description-length.md。 - 将归档和候选 metadata 暂存为一次性 discovery,并返回前端选择;此阶段不写入 Vault。
- 用户确认后才落盘
vault/.agents/skills/<name>/(整目录拷贝,含references/等): - 目标已存在 → 默认不覆盖,报「已存在,是否更新」(沿用
ensure_vault不覆盖用户文件的原则); - 在 skill 目录写
agentero-skill.json来源记录(source URL + ref + 安装时间),为将来「检查更新」留钩子(参考skills-lock.json/ Obsidian BRAT)。 - 不落 catalog(skill 不是论文;
Urlkind 已有identifier_kind_column → None先例),不建papers/条目、不跑paper_commit。
私有 repo / 浅 clone 回退、GitLab 支持均延后。
4. 交互流程¶
- 入口:魔棒粘贴 →
lookup_import_batch;广场 Skill 推荐 卡片点击同一条路(importPlazaSkillRepo→lookupSubmit)。batch 内论文与 skill 可混合,逐条按 kind 分发。 - 进度沿用左下角后台任务条(
job:progress)。 - 当前实现先返回
LookupImportBatchResult.skillCandidates,前端打开多选 Dialog。--skill <name>、GitHub tree 子目录会缩小候选范围。 - 用户取消时删除 discovery 临时包;确认后调用
skill_install,再refreshTree+ toast 汇总安装结果。不openPaper、不进补资产队列。论文和 Skill 可混合提交。 - 远程 Vault:首版禁用(提示暂不支持),后续经 remote bridge + SFTP 镜像(
features/remote/launch.rs已有 skills 镜像逻辑)。
5. 安全¶
- tar 解压必须走
sanitize_tar_path防路径穿越;限制解压总大小与文件数上限。 - 只下载解包,不执行任何脚本(skill 的
scripts/仅落盘);不 shell out 到npx/git。 - SKILL.md 是注入 Agent prompt 的内容,安装第三方 skill 等于引入外部指令——安装 toast / 选择对话框中提示来源,用户自担信任决策(BYOA 一致原则)。
6. 已验证输入¶
| 输入 | 解析结果 |
|---|---|
https://github.com/mattpocock/skills |
GitHub 仓库 mattpocock/skills,默认分支 |
https://github.com/alchaincyf/nuwa-skill |
GitHub 仓库 alchaincyf/nuwa-skill,默认分支 |
npx skills add https://github.com/anthropics/skills --skill pptx |
GitHub 仓库 anthropics/skills,Skill 过滤 pptx |
回归测试位于 crates/agentero-core/src/features/paper/scholar_api/sources/skill.rs 的
parses_requested_skill_import_examples,import/search_router.rs 仍保留
extract_primary_identifier 的优先级测试。
7. 后续¶
| 阶段 | 内容 |
|---|---|
| P2 | 已装 Skill 的「检查更新 / 重装」(基于 agentero-skill.json);#ref pin;多候选选择对话框 |
| P3 | 私有 repo(gh / git 回退)、GitLab、.well-known 源、远程 Vault |