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

9.8 KiB
Raw Permalink Blame History

use_vala_skillhub

管理 Vala SkillHub 上的技能:推送(上传)和安装。

SkillHub 基于 Gitea每个技能对应一个独立的 Git 仓库。推送时使用 ./tmp 临时目录,不在 ./skills 内创建 .git,避免影响 workspace 级别的 git 备份。

命名规则

仓库名格式:{skill_name}.{source_name}

  • skill_name:技能目录名(如 cron_jobweb_scraper
  • source_name:来源名称,即当前数字员工的 namexiaoxi
  • 如果 source_namevala,表示公司级别的官方技能

示例:

  • 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用于组合仓库名

如果配置文件不存在,请询问用户获取以上信息后创建:

cat > ./.vala_skillhub_config <<EOF
GITEA_URL=https://git.valavala.com
GITEA_TOKEN=<token>
GITEA_OWNER=vala_skillhub
SOURCE_NAME=<name>
EOF

后续操作前先加载配置:

source ./.vala_skillhub_config

操作一:推送技能到 SkillHub

将本地 ./skills 下的技能目录推送到 SkillHub。

核心原则:使用 ./tmp/skill_push/ 作为临时工作区,不在 ./skills 内执行任何 git 操作,保持 workspace 干净。

流程

  1. 确定仓库名repo_name = {skill_dir_name}.{SOURCE_NAME}

  2. 检查远程仓库是否存在

    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. 创建远程仓库

    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. 复制到临时目录并推送

    # 清理并准备临时目录
    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. 清理临时目录

    cd -
    rm -rf ./tmp/skill_push/${repo_name}
    

批量推送

遍历 ./skills/ 下所有子目录,对每个目录重复以上流程。注意跳过 use_vala_skillhub 目录本身。


操作二:安装 / 更新技能

从 SkillHub 下载技能到本地 ./skills 目录。若本地已存在同名目录,则清空后重新下载,确保与远程版本一致。

注意:不使用 git clone,而是下载归档解压,避免在 ./skills 下产生 .git 目录。

流程

  1. 确定要安装的仓库名(完整名,如 cron_job.xiaoxi

  2. 下载并解压(已存在则先清空再覆盖):

    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 上的技能

curl -s "${GITEA_URL}/api/v1/orgs/${GITEA_OWNER}/repos?page=1&limit=50&sort=updated" \
  -H "Authorization: token ${GITEA_TOKEN}"

返回 JSON 数组,每个元素包含 namedescriptionupdated_at 等字段。如结果满 50 条,继续翻页 page=2


操作四:自动同步(变更检测 + 自动推送)

当 skill 发生新增或更新时,自动检测变更并仅推送有变化的 skill。

哈希状态文件

使用 ./.vala_skill_hashesworkspace 根目录下)记录每个 skill 上次推送时的内容哈希,格式为每行一条记录:

skill_dir_name hash

示例:

cron_job a3f2b8c9...
web_scraper 7d1e4f6a...

计算 skill 目录哈希

对 skill 目录内所有文件(含文件路径)计算综合哈希,确保文件新增、删除、重命名、内容修改都能被检测到:

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. 加载配置和哈希状态

    source ./.vala_skillhub_config
    HASH_FILE=./.vala_skill_hashes
    touch "${HASH_FILE}"
    
  2. 遍历 ./skills/ 下所有 skill 目录,对每个 skill

    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无需遍历所有目录

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 个(无变更)