use_vala_skillhub.vala/SKILL.md
2026-04-01 23:22:47 +08:00

293 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# use_vala_skillhub
管理 Vala SkillHub 上的技能:推送(上传)和安装。
SkillHub 基于 Gitea每个技能对应一个独立的 Git 仓库。推送时使用 `./tmp` 临时目录,不在 `./skills` 内创建 `.git`,避免影响 workspace 级别的 git 备份。
## 命名规则
仓库名格式:`{skill_name}.{source_name}`
- `skill_name`:技能目录名(如 `cron_job`、`web_scraper`
- `source_name`:来源名称,即当前数字员工的 name`xiaoxi`
- 如果 `source_name``vala`,表示公司级别的官方技能
示例:
- `cron_job.xiaoxi` — xiaoxi 的定时任务技能
- `web_scraper.vala` — 公司官方的爬虫技能
## 配置
操作前需要确认以下配置(保存到 `./.vala_skillhub_config`,即当前 workspace 根目录下):
| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| `GITEA_URL` | Gitea 服务地址 | `https://git.valavala.com` |
| `GITEA_TOKEN` | Gitea API Token需有创建仓库和推送权限 | — |
| `GITEA_OWNER` | SkillHub 组织名 | `vala_skillhub` |
| `SOURCE_NAME` | 当前数字员工的 name用于组合仓库名 | — |
如果配置文件不存在,请询问用户获取以上信息后创建:
```bash
cat > ./.vala_skillhub_config <<EOF
GITEA_URL=https://git.valavala.com
GITEA_TOKEN=<token>
GITEA_OWNER=vala_skillhub
SOURCE_NAME=<name>
EOF
```
后续操作前先加载配置:
```bash
source ./.vala_skillhub_config
```
---
## 操作一:推送技能到 SkillHub
将本地 `./skills` 下的技能目录推送到 SkillHub。
**核心原则**:使用 `./tmp/skill_push/` 作为临时工作区,不在 `./skills` 内执行任何 git 操作,保持 workspace 干净。
### 流程
1. **确定仓库名**`repo_name = {skill_dir_name}.{SOURCE_NAME}`
2. **检查远程仓库是否存在**
```bash
curl -s -o /dev/null -w "%{http_code}" \
"${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${repo_name}" \
-H "Authorization: token ${GITEA_TOKEN}"
```
- 返回 200 → 仓库已存在,跳到步骤 4
- 返回 404 → 需要创建,执行步骤 3
3. **创建远程仓库**
```bash
curl -s -X POST "${GITEA_URL}/api/v1/orgs/${GITEA_OWNER}/repos" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name": "'${repo_name}'", "private": false, "description": "技能描述", "auto_init": false}'
```
4. **复制到临时目录并推送**
```bash
# 清理并准备临时目录
rm -rf ./tmp/skill_push/${repo_name}
mkdir -p ./tmp/skill_push/${repo_name}
# 复制技能内容(不含隐藏文件的 .git 等)
cp -r ./skills/${skill_dir_name}/* ./tmp/skill_push/${repo_name}/
cp -r ./skills/${skill_dir_name}/.[!.]* ./tmp/skill_push/${repo_name}/ 2>/dev/null || true
# 在临时目录中执行 git 操作
cd ./tmp/skill_push/${repo_name}
git init
git checkout -b main
git add -A
git commit -m "update: sync skill $(date +%Y-%m-%d)"
git remote add origin https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git
git push -u origin main --force
```
5. **清理临时目录**
```bash
cd -
rm -rf ./tmp/skill_push/${repo_name}
```
### 批量推送
遍历 `./skills/` 下所有子目录,对每个目录重复以上流程。注意跳过 `use_vala_skillhub` 目录本身。
---
## 操作二:安装 / 更新技能
从 SkillHub 下载技能到本地 `./skills` 目录。若本地已存在同名目录,则**清空后重新下载**,确保与远程版本一致。
**注意**:不使用 `git clone`,而是下载归档解压,避免在 `./skills` 下产生 `.git` 目录。
### 流程
1. **确定要安装的仓库名**(完整名,如 `cron_job.xiaoxi`
2. **下载并解压**(已存在则先清空再覆盖):
```bash
repo_name="cron_job.xiaoxi"
target_dir="./skills/${repo_name}"
# 如果已存在,清空目录内容以确保与远程一致(删除远程已移除的文件)
rm -rf "${target_dir}"
mkdir -p "${target_dir}"
# 通过 Gitea API 下载 tar.gz 归档并解压(自动尝试 main/master
curl -sL "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${repo_name}/archive/main.tar.gz" \
-H "Authorization: token ${GITEA_TOKEN}" \
| tar xz --strip-components=1 -C "${target_dir}" 2>/dev/null \
|| curl -sL "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${repo_name}/archive/master.tar.gz" \
-H "Authorization: token ${GITEA_TOKEN}" \
| tar xz --strip-components=1 -C "${target_dir}"
```
---
## 操作三:列出 SkillHub 上的技能
```bash
curl -s "${GITEA_URL}/api/v1/orgs/${GITEA_OWNER}/repos?page=1&limit=50&sort=updated" \
-H "Authorization: token ${GITEA_TOKEN}"
```
返回 JSON 数组,每个元素包含 `name`、`description`、`updated_at` 等字段。如结果满 50 条,继续翻页 `page=2`
---
## 操作四:自动同步(变更检测 + 自动推送)
当 skill 发生新增或更新时,自动检测变更并仅推送有变化的 skill。
### 哈希状态文件
使用 `./.vala_skill_hashes`workspace 根目录下)记录每个 skill 上次推送时的内容哈希,格式为每行一条记录:
```
skill_dir_name hash
```
示例:
```
cron_job a3f2b8c9...
web_scraper 7d1e4f6a...
```
### 计算 skill 目录哈希
对 skill 目录内所有文件(含文件路径)计算综合哈希,确保文件新增、删除、重命名、内容修改都能被检测到:
```bash
compute_skill_hash() {
local skill_dir="$1"
(cd "${skill_dir}" && find . -type f -not -path '*/\.*' | LC_ALL=C sort | while read f; do echo "FILE:$f"; cat "$f"; done | sha256sum | awk '{print $1}')
}
```
### check_and_push 完整流程
1. **加载配置和哈希状态**
```bash
source ./.vala_skillhub_config
HASH_FILE=./.vala_skill_hashes
touch "${HASH_FILE}"
```
2. **遍历 `./skills/` 下所有 skill 目录**,对每个 skill
```bash
for skill_dir in ./skills/*/; do
skill_name=$(basename "${skill_dir}")
# 跳过 use_vala_skillhub 自身
if [ "${skill_name}" = "use_vala_skillhub" ]; then
continue
fi
# 计算当前哈希
current_hash=$(compute_skill_hash "${skill_dir}")
# 读取上次推送的哈希
stored_hash=$(grep "^${skill_name} " "${HASH_FILE}" | awk '{print $2}')
if [ "${current_hash}" = "${stored_hash}" ]; then
echo "[skip] ${skill_name} — 无变更"
continue
fi
echo "[sync] ${skill_name} — 检测到变更,开始推送..."
# 执行推送(同操作一的流程)
repo_name="${skill_name}.${SOURCE_NAME}"
# 检查远程仓库是否存在
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
"${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${repo_name}" \
-H "Authorization: token ${GITEA_TOKEN}")
# 如果不存在则创建
if [ "${http_code}" = "404" ]; then
# 从 skill.json 读取描述(如果有)
desc=""
if [ -f "${skill_dir}/skill.json" ]; then
desc=$(cat "${skill_dir}/skill.json" | grep '"description"' | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\(.*\)".*/\1/')
fi
curl -s -X POST "${GITEA_URL}/api/v1/orgs/${GITEA_OWNER}/repos" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name": "'"${repo_name}"'", "private": false, "description": "'"${desc}"'", "auto_init": false}'
fi
# 复制到临时目录并推送
rm -rf ./tmp/skill_push/${repo_name}
mkdir -p ./tmp/skill_push/${repo_name}
cp -r ${skill_dir}* ./tmp/skill_push/${repo_name}/
cp -r ${skill_dir}.[!.]* ./tmp/skill_push/${repo_name}/ 2>/dev/null || true
cd ./tmp/skill_push/${repo_name}
git init
git checkout -b main
git add -A
git commit -m "auto-sync: ${skill_name} $(date +%Y-%m-%d_%H:%M)"
git remote add origin "https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}/${GITEA_OWNER}/${repo_name}.git"
git push -u origin main --force
cd -
# 清理临时目录
rm -rf ./tmp/skill_push/${repo_name}
# 更新哈希状态文件
# 先移除旧记录,再追加新记录
grep -v "^${skill_name} " "${HASH_FILE}" > "${HASH_FILE}.tmp" || true
echo "${skill_name} ${current_hash}" >> "${HASH_FILE}.tmp"
mv "${HASH_FILE}.tmp" "${HASH_FILE}"
echo "[done] ${skill_name} — 推送完成"
done
```
3. **输出同步摘要**:推送完成后,汇总本次同步了哪些 skill跳过了哪些
### 单个 skill 的快速同步
当你明确知道哪个 skill 发生了变更时,可以仅对该 skill 执行 check_and_push无需遍历所有目录
```bash
skill_name="目标skill名"
skill_dir="./skills/${skill_name}"
# 然后执行上面循环体中的逻辑
```
---
## 数字员工行为规范(重要)
作为数字员工,你**必须**在以下场景中自动执行 `check_and_push`
1. **创建新 skill 后** — 在 `./skills/` 下新建了 skill 目录并完成编写后,立即执行同步
2. **修改现有 skill 后** — 对 `./skills/` 下任何 skill 的文件做了修改后,立即执行同步
3. **删除 skill 文件后** — 如果删除了 skill 中的某些文件(重构等),同步以保持远程一致
4. **定时兜底**(可选) — 如果你拥有 `cron_job` 技能,建议设置每日一次的全量 check_and_push 作为安全网
### 推送时机建议
- **立即推送**skill 的功能性变更完成且验证通过后
- **不要推送**:正在编辑中间态、尚未完成的 skill
- **批量场景**:如果一次性修改了多个 skill在全部完成后执行一次全量 check_and_push 即可
### 自动推送日志
每次推送后,建议在控制台输出简短日志,方便追溯:
```
[auto-sync] 2025-04-01 23:00 — 推送 2 个 skill: cron_job, web_scraper | 跳过 3 个(无变更)
```