feat: initialize OmniClaw skills registry
This commit is contained in:
99
tools/install.sh
Executable file
99
tools/install.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SKILL_NAME="${1:-}"
|
||||
VERSION="${2:-latest}"
|
||||
REPO_URL="${OMNICLAW_SKILLS_REPO:-https://git.omniclaw.store/zsb/omniclaw-skills.git}"
|
||||
RAW_BASE_URL="${OMNICLAW_SKILLS_RAW_BASE_URL:-https://git.omniclaw.store/zsb/omniclaw-skills/raw/branch/main}"
|
||||
DEST_DIR="${CODEX_HOME:-$HOME/.codex}/skills"
|
||||
|
||||
if [[ -z "$SKILL_NAME" ]]; then
|
||||
echo "Usage: install.sh <skill-name> [version]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
require_cmd() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "Missing required command: $1" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
require_cmd mktemp
|
||||
require_cmd node
|
||||
require_cmd tar
|
||||
require_cmd shasum
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$tmp_dir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
manifest="$tmp_dir/manifest.json"
|
||||
if [[ -d "$RAW_BASE_URL" && -f "$RAW_BASE_URL/registry/manifest.json" ]]; then
|
||||
cp "$RAW_BASE_URL/registry/manifest.json" "$manifest"
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$RAW_BASE_URL/registry/manifest.json" -o "$manifest" || true
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -qO "$manifest" "$RAW_BASE_URL/registry/manifest.json" || true
|
||||
else
|
||||
: > "$manifest"
|
||||
fi
|
||||
|
||||
if [[ ! -s "$manifest" ]]; then
|
||||
require_cmd git
|
||||
git clone --depth 1 "$REPO_URL" "$tmp_dir/repo"
|
||||
if [[ ! -f "$tmp_dir/repo/registry/manifest.json" ]]; then
|
||||
echo "Unable to find registry/manifest.json from $REPO_URL" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp "$tmp_dir/repo/registry/manifest.json" "$manifest"
|
||||
RAW_BASE_URL="$tmp_dir/repo"
|
||||
fi
|
||||
|
||||
node_script='
|
||||
const fs = require("fs");
|
||||
const manifest = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
|
||||
const name = process.argv[2];
|
||||
const version = process.argv[3];
|
||||
const skill = manifest.skills.find((item) => item.name === name && (version === "latest" || item.version === version));
|
||||
if (!skill) {
|
||||
console.error(`Skill not found: ${name}@${version}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(JSON.stringify(skill));
|
||||
'
|
||||
|
||||
skill_json="$(node -e "$node_script" "$manifest" "$SKILL_NAME" "$VERSION")"
|
||||
package_path="$(printf '%s' "$skill_json" | node -e 'let s="";process.stdin.on("data",c=>s+=c);process.stdin.on("end",()=>console.log(JSON.parse(s).package));')"
|
||||
expected_sha="$(printf '%s' "$skill_json" | node -e 'let s="";process.stdin.on("data",c=>s+=c);process.stdin.on("end",()=>console.log(JSON.parse(s).sha256));')"
|
||||
|
||||
archive="$tmp_dir/skill.tar.gz"
|
||||
if [[ -d "$RAW_BASE_URL" ]]; then
|
||||
cp "$RAW_BASE_URL/$package_path" "$archive"
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$RAW_BASE_URL/$package_path" -o "$archive"
|
||||
else
|
||||
wget -qO "$archive" "$RAW_BASE_URL/$package_path"
|
||||
fi
|
||||
|
||||
actual_sha="$(shasum -a 256 "$archive" | awk '{print $1}')"
|
||||
if [[ "$actual_sha" != "$expected_sha" ]]; then
|
||||
echo "Checksum mismatch for $package_path" >&2
|
||||
echo "expected: $expected_sha" >&2
|
||||
echo "actual: $actual_sha" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
target="$DEST_DIR/$SKILL_NAME"
|
||||
if [[ -e "$target" ]]; then
|
||||
backup="$target.backup.$(date +%Y%m%d%H%M%S)"
|
||||
mv "$target" "$backup"
|
||||
echo "Existing skill moved to $backup"
|
||||
fi
|
||||
|
||||
tar -xzf "$archive" -C "$DEST_DIR"
|
||||
echo "Installed $SKILL_NAME to $DEST_DIR/$SKILL_NAME"
|
||||
echo "Restart Codex to pick up new skills."
|
||||
Reference in New Issue
Block a user