|
13 | 13 | rm -rf "$OUT_DIR" |
14 | 14 | mkdir -p "$OUT_DIR" |
15 | 15 |
|
16 | | -STAGE_DIR="$(mktemp -d)" |
17 | | -trap 'rm -rf "$STAGE_DIR"' EXIT |
| 16 | +INNER_DIR="$(mktemp -d)" |
| 17 | +trap 'rm -rf "$INNER_DIR"' EXIT |
18 | 18 |
|
19 | | -stage_one() { |
| 19 | +build_one() { |
20 | 20 | local skill_dir="$1" |
21 | 21 | local name |
22 | | - local target |
| 22 | + local stage_dir |
23 | 23 | local refs |
24 | 24 |
|
25 | 25 | name="$(basename "$skill_dir")" |
26 | | - target="$STAGE_DIR/$name" |
27 | | - mkdir -p "$target" |
| 26 | + stage_dir="$(mktemp -d)" |
28 | 27 |
|
29 | | - cp "$skill_dir/SKILL.md" "$target/SKILL.md" |
| 28 | + cp "$skill_dir/SKILL.md" "$stage_dir/SKILL.md" |
30 | 29 |
|
31 | | - refs="$(grep -Eo '知识库/[^`,。 、)]*\.md' "$skill_dir/SKILL.md" || true)" |
| 30 | + refs="$(grep -Eo '知识库/[^`,。 、)]*\.md' "$skill_dir/SKILL.md" || true)" |
32 | 31 | if [ -n "$refs" ]; then |
33 | 32 | while IFS= read -r ref; do |
34 | 33 | [ -n "$ref" ] || continue |
35 | 34 | if [ -f "$ROOT_DIR/$ref" ]; then |
36 | | - mkdir -p "$target/$(dirname "$ref")" |
37 | | - cp "$ROOT_DIR/$ref" "$target/$ref" |
| 35 | + mkdir -p "$stage_dir/$(dirname "$ref")" |
| 36 | + cp "$ROOT_DIR/$ref" "$stage_dir/$ref" |
38 | 37 | fi |
39 | 38 | done <<< "$refs" |
40 | 39 | fi |
41 | 40 |
|
42 | | - echo "staged $name" |
43 | | -} |
44 | | - |
45 | | -for skill_md in "$ROOT_DIR"/skills/*/SKILL.md; do |
46 | | - stage_one "$(dirname "$skill_md")" |
47 | | -done |
48 | | - |
49 | | -python3 - "$STAGE_DIR" "$OUT_DIR/dbskill-${VERSION}.zip" <<'PY' |
| 41 | + python3 - "$stage_dir" "$INNER_DIR/${name}.zip" <<'PY' |
50 | 42 | import os |
51 | 43 | import sys |
52 | 44 | import zipfile |
53 | 45 |
|
54 | | -stage_dir, archive_path = sys.argv[1], sys.argv[2] |
| 46 | +source_dir, archive_path = sys.argv[1], sys.argv[2] |
55 | 47 |
|
56 | 48 | with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as archive: |
57 | | - for root, _, files in os.walk(stage_dir): |
| 49 | + for root, _, files in os.walk(source_dir): |
58 | 50 | for filename in files: |
59 | 51 | path = os.path.join(root, filename) |
60 | | - archive.write(path, os.path.relpath(path, stage_dir)) |
| 52 | + archive.write(path, os.path.relpath(path, source_dir)) |
61 | 53 | PY |
62 | 54 |
|
63 | | -cat > "$OUT_DIR/README.md" <<EOF |
64 | | -# dbskill skill 包 |
| 55 | + rm -rf "$stage_dir" |
| 56 | + echo "built ${name}.zip" |
| 57 | +} |
| 58 | + |
| 59 | +for skill_md in "$ROOT_DIR"/skills/*/SKILL.md; do |
| 60 | + build_one "$(dirname "$skill_md")" |
| 61 | +done |
65 | 62 |
|
66 | | -版本:${VERSION} |
| 63 | +cat > "$INNER_DIR/README.md" <<EOF |
| 64 | +# dbskill ${VERSION} |
67 | 65 |
|
68 | | -从 GitHub Releases 下载 dbskill-${VERSION}.zip。zip 的根目录是 17 个 skill 子文件夹,每个子文件夹里有一个标准命名的 SKILL.md(带 YAML frontmatter,含 name + description),并附带该 skill 引用的知识库文件。 |
| 66 | +里面是 17 个独立的 skill zip 包。每个 zip 解压后根目录是 SKILL.md(带 YAML frontmatter,含 name + description),并附带该 skill 引用的知识库文件。 |
69 | 67 |
|
70 | | -格式遵循 Anthropic Skills 规范,可用于 Trae Solo、Claude Code 等支持该格式的产品。整体上传 zip,或拆出需要的子文件夹打包后单独上传都可以。 |
| 68 | +格式遵循 Anthropic Skills 规范,可用于 Trae Solo、Claude Code 等支持该格式的产品。逐个上传到 Trae Solo 的「上传技能」窗口即可。 |
71 | 69 | EOF |
72 | 70 |
|
| 71 | +python3 - "$INNER_DIR" "$OUT_DIR/dbskill-${VERSION}.zip" <<'PY' |
| 72 | +import os |
| 73 | +import sys |
| 74 | +import zipfile |
| 75 | +
|
| 76 | +inner_dir, archive_path = sys.argv[1], sys.argv[2] |
| 77 | +
|
| 78 | +with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as archive: |
| 79 | + for filename in sorted(os.listdir(inner_dir)): |
| 80 | + archive.write(os.path.join(inner_dir, filename), filename) |
| 81 | +PY |
| 82 | + |
73 | 83 | echo |
74 | 84 | echo "done: $OUT_DIR/dbskill-${VERSION}.zip" |
0 commit comments